how to use user input array in heap sorting - c++

I'm a beginner so please excuse me if it is a dumb question.
I am trying to code a heap sort that takes input from user in an array and heap sorts it but i can not find a way to implement user input array in my code.
at the end, in the main function, i have to use array arr[]={} but i either have to define the elements or the number of elements so it creates zeros if i define the array as arr[10]={}
here is the code :
// Heap Sort in C++
#include <iostream>
using namespace std;
void heapify(int arr[], int n, int i) {
// Find largest among root, left child and right child
int largest = i;
int left = 2 * i + 1;
int right = 2 * i + 2;
if (left < n && arr[left] > arr[largest])
largest = left;
if (right < n && arr[right] > arr[largest])
largest = right;
// Swap and continue heapifying if root is not largest
if (largest != i) {
swap(arr[i], arr[largest]);
heapify(arr, n, largest);
}
}
// main function to do heap sort
void heapSort(int arr[], int n) {
// Build max heap
for (int i = n / 2 - 1; i >= 0; i--)
heapify(arr, n, i);
// Heap sort
for (int i = n - 1; i >= 0; i--) {
swap(arr[0], arr[i]);
// Heapify root element to get highest element at root again
heapify(arr, i, 0);
}
}
// Print an array
void printArray(int arr[], int n) {
for (int i = 0; i < n; ++i)
cout << arr[i] << " ";
cout << "\n";
}
// Driver code
int main() {
int arr[10] = { };
cout << "Enter the numbers : " << endl;
for (int x = 1; x <= 5; x++)
{
cin >> arr[x];
}
int n = sizeof(arr) / sizeof(arr[0]);
heapSort(arr, n);
cout << "Sorted array is \n";
printArray(arr, n);
}
here is the output :
code output image

You can consider std::vector and pass it by reference to your heapify(...) to save memory.

Related

Not able to find error in my Heap Sort Code. Not executing properly. C++

Please help. I have reviewed it and seem to be missing the error. It seems to be exiting out of the function Max_Heapify and not running my second loop to print the sorted array. This was for an assignment I have already turned in but I am trying to learn the error of my ways to make sure I can do well on the test.
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
// declare global variable of heap size
int heap_size = 7;
// function to determine left child node of the tree
int Left(int i){
return 2*i+1;
}
// function to determine right child node of the tree
int Right(int i){
return 2*i + 2;
}
// create heap tree
void Max_Heapify (int array[], int index){
int left_child_index = Left(index);
int right_child_index = Right(index);
int largest;
// check if left child is smaller than heap size and if left child is bigger than parent
// if so, save variable as largest value, otherwise, largest value will stay as index
if ( (left_child_index < heap_size) && (array[left_child_index] > array[index]) )
largest = left_child_index;
else largest = index;
// check if right child is smaller than heap and if bigger than largest value
if ((right_child_index < heap_size) && (array[right_child_index] > array[largest]) )
largest = right_child_index;
// exchange largest values
if (largest != index)
swap(array[index], array[largest]);
Max_Heapify(array,largest);
}
// check leaves
void Build_Max_Heap(int array[]){
for (int i = (heap_size / 2 ) - 1; i >= 0; i--)
Max_Heapify (array, i);
}
void Heapsort(int array[]) {
Build_Max_Heap(array);
for (int i = heap_size-1; i >= 0; i--){
swap(array[0], array[i]);
Max_Heapify(array,0);
}
}
int main(){
int arr[7] = {21, 9, 50, 7, 6, 33, 77};
cout << "Non Heapified Array: " << endl;
for (int i = 0; i < heap_size; i++){
cout << arr[i] << endl;
}
Heapsort(arr);
for (int i = 0; i < heap_size; i++){
cout << arr[i]<< endl;
}
}
Your MaxHeapify never terminates. You should call MaxHeapify only if largest is not i. If largest is i, then nothing needs to be done here as the elements are already heapified.
if (largest != index){
swap(array[index], array[largest]);
Max_Heapify(array,largest);
}

Kth smallest element- can't create array more than the size of k

I have implemented an algorithm that solves the problem of finding the kth smallest element in an unsorted array. I have used the heap structure, and optimized the code by relying on this formula,
k1 = n - k + 1
k1 being the k1th largest element, so I go for the smaller of k and k1.
Still, I couldn't pass the time limit error on an online judge. I don't know if there will be any further more better complexity having in mind that I have to create an array no more than the size of k; maybe less than k possible? Or there is another way to solve this problem other than using the heap structure.
1 <= k <= n <= 105
The code:
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
void minHeapify(int arr[], int n, int i)
{
int largest = i; // Initialize largest as root
int l = 2 * i + 1; // left = 2*i + 1
int r = 2 * i + 2; // right = 2*i + 2
if (l < n && arr[l] < arr[largest])
largest = l;
if (r < n && arr[r] < arr[largest])
largest = r;
if (largest != i) {
swap(arr[i], arr[largest]);
minHeapify(arr, n, largest);
}
}
void maxHeapify(int arr[], int n, int i)
{
int smallest = i; // Initialize largest as root
int l = 2 * i + 1; // left = 2*i + 1
int r = 2 * i + 2; // right = 2*i + 2
if (l < n && arr[l] > arr[smallest])
smallest = l;
if (r < n && arr[r] > arr[smallest])
smallest = r;
if (smallest != i) {
swap(arr[i], arr[smallest]);
maxHeapify(arr, n, smallest);
}
}
void buildMinHeap(int a[], int n) {
for (int i = n / 2; i >= 0; i--)
minHeapify(a, n, i);
}
void buildMaxHeap(int a[], int n) {
for (int i = n / 2; i >= 0; i--)
maxHeapify(a, n, i);
}
int kthsmallest(int minHeap[], int k, int n) {
int i, temp;
for (i = 0; i < k; i++)
cin >> minHeap[i];
buildMaxHeap(minHeap, k);
for (i = k; i < n; i++)
{
cin >> temp;
if (temp < minHeap[0])
{
minHeap[0] = temp;
maxHeapify(minHeap, k, 0);
}
}
return minHeap[0];
}
int kthlargest(int minHeap[], int k, int n) {
int i, temp;
for (i = 0; i < k; i++)
cin >> minHeap[i];
buildMinHeap(minHeap, k);
for (i = k; i < n; i++)
{
cin >> temp;
if (temp > minHeap[0])
{
minHeap[0] = temp;
minHeapify(minHeap, k, 0);
}
}
return minHeap[0];
}
int main() {//kth smallest element
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
int n, k, k1;
cin >> n >> k;
k1 = n - k + 1;//kth smallest element is the same as k1th largest element
if (k < k1) {
int *minHeap = new int[k];
cout << kthsmallest(minHeap, k, n);
}
else {
int *minHeap = new int[k1];
cout << kthlargest(minHeap, k1, n);
}
return 0;
}
Please if you could help finding a better time complexity?
Problem:
Find the kth largest element of an array
Memory limit: 256 MBs
Time limit: 1 s
Input: input.txt
Output: output.txt
Task:
You are given an array of n integers and a natural k.
You have to find the kth largest element of the array.
You can't create array consisting of more than k elements.
Input:
The first line contains a natural n (1 ≤ n≤105) – the
quantity of elements of the array, and the natural k.
The second line contains n numbers – the elements of the array.
Output:
The kth largest element of the array.
Example:
Input | Output
-------------+-----------
6 2 | 7
7 4 6 3 9 1 |
The time complexity is optimal, but you can make your code a tiny bit more efficient:
Don't use recursion, but an iterative solution
Don't use swap, but keep the original value in memory while copying child values to their parents and only store the initial value once you have reached the appropriate slot.
Don't perform twice 2 * i: the other child node is just the next one.
Let the heapify functions take an extra argument, which can be either the current value at index i, or the replacement value for it. This saves one assignment.
Here is how that would look for two heapify functions:
void minHeapify(int arr[], int n, int i, int key) { // add key as parameter
while (true) { // iterative
int child = 2 * i + 1; // do this only for left child, and limit number of variables
if (child+1 < n && arr[child] > arr[child+1]) // get child with least value
child++; // the right child is just one index further
if (child >= n || key <= arr[child]) break;
arr[i] = arr[child]; // don't swap, just copy child value to parent
i = child; // move down
}
arr[i] = key; // finally put the original value in the correct place
}
void maxHeapify(int arr[], int n, int i, int key) { // add key as parameter
while (true) { // iterative
int child = 2 * i + 1; // do this only for left child, and limit number of variables
if (child+1 < n && arr[child] < arr[child+1]) // get child with greatest value
child++; // the right child is just one index further
if (child >= n || key >= arr[child]) break;
arr[i] = arr[child]; // don't swap, just copy child value to parent
i = child; // move down
}
arr[i] = key; // finally put the original value in the correct place
}
void buildMinHeap(int a[], int n) {
for (int i = n / 2; i >= 0; i--)
minHeapify(a, n, i, a[i]); // pass a[i] also
}
void buildMaxHeap(int a[], int n) {
for (int i = n / 2; i >= 0; i--)
maxHeapify(a, n, i, a[i]); // pass a[i] also
}
int kthsmallest(int heap[], int k, int n) {
int i, temp;
for (i = 0; i < k; i++)
cin >> heap[i];
buildMaxHeap(heap, k);
for (i = k; i < n; i++) {
cin >> temp;
if (temp < heap[0])
maxHeapify(heap, k, 0, temp); // pass temp
}
return heap[0];
}
int kthlargest(int heap[], int k, int n) {
int i, temp;
for (i = 0; i < k; i++)
cin >> heap[i];
buildMinHeap(heap, k);
for (i = k; i < n; i++) {
cin >> temp;
if (temp > heap[0])
minHeapify(heap, k, 0, temp); // pass temp
}
return heap[0];
}
In main function you could make a special case for when k == 1 or k == n, so no heap is needed, just min() or max().
One strange thing is that the challenge you link to speaks of "kth largest" while you speak of "kth smallest". Maybe you mixed up.
So here is the code when the job is to return the kth smallest. But please check the challenge whether you should not have done it for kth largest:
int main() {//kth smallest element
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
int n, k, k1;
cin >> n >> k;
k1 = n - k + 1;//kth smallest element is the same as k1th largest element
if (k == 1) {
int curr, next;
cin >> curr;
for (int i = 1; i < n; i++) {
cin >> next;
curr = min(curr, next);
}
cout << curr;
} else if (k1 == 1) {
int curr, next;
cin >> curr;
for (int i = 1; i < n; i++) {
cin >> next;
curr = max(curr, next);
}
cout << curr;
} else if (k < k1) {
int *heap = new int[k];
cout << kthsmallest(heap, k, n);
} else {
int *heap = new int[k1];
cout << kthlargest(heap, k1, n);
}
return 0;
}
You're making the assumption that using a smaller heap is always the best choice. You might want to re-think that.
For example, imagine you want to select the 96th smallest number from a list of 100. If you use a heap of size 96, then you'll do:
Build a heap with 96 items. buildHeap is O(n), and in this case n is 96.
Do up to 4 insertions into a heap of 96 items. That'll be 4*log(96).
If you use a heap of size 4, then you'll do:
Build a heap with 4 items.
Do up to 96 insertions into a heap of 4 items. That'll be 96*log(4).
The first option is 96 + 4*log(96). The base-2 log of 96 is about 6.58. So the insertions will cost 26.32, for a total of 122.32.
The second option, with the smaller heap, is 4 + 96*log(4). log(4) is 2, so you end up with 4 + 196, or a total of 196.
The smaller heap is a big loser here.
In general, you want to use the larger heap when (k + (n-k)*log(k)) < ((n-k) + k*log(n-k)).
Also:
The real-world running time of the heap selection algorithm is kind of sensitive to the order in which items are presented. For example, if you're looking for 1000th smallest number in an array of 100,000, it's going to run much faster if the array is in ascending order than if it's in descending order. The reason?
Because in the ascending case, you build your initial heap with the first 1,000 items and then you never have to modify the heap again because there is none of the following items are smaller than the largest item on the heap.
But if the array is in descending order, then every item you look at will be smaller than the largest item on the heap, which means you'd be doing a heap insertion for all 99,000 remaining items.
Imagine how your code would perform if one of the test cases is a large array in descending order.
Unless you've already proven that your way of selecting which heap size to use is clearly better, you might want to consider just going with "select kth smallest," using a maxheap of size k, regardless.

Getting a weird negative number in my output when using an array I modified in one function, in another function

I am writing a program that takes a user-inputted list of up to 25 integers, then prints the sorted list using bubble sorting, the sorted list in descending order, and some other info about the list like the median, minimum and maximum, and mode.
I have tested all of my functions within the program individually on an array I created using initializer lists (not from user input/cin) and they work fine, but when I run the program something is off. For example, when I input 1,2,3,4, the function that prints the sorted list in descending order prints 3,2,1, -858993460. It always leaves out the greatest integer and adds on -858993460 at the end no matter what values I put into the input array. Here's the relevant part of my code:
#include <iostream>
using namespace std;
void input(int ulist[26], int& n);
void Bubblesort(int ulist[26], int slist[26], int n);
void print(int list[26], int n);
int n;
void reversesort(int slist[26], int n);
void main()
{
int ulist[26], slist[26];
input(ulist, n);
cout << "Unsorted";
print(ulist, n);
cout << "Sorted";
Bubblesort(ulist, slist, n);
print(slist, n);
reversesort(slist, n);
cin >> n;
}
void input(int ulist[26], int& n)
{
int i(0), value;
cout << "enter value : \n";
cin >> value;
while (i < 25 && value != -999)
{
ulist[i] = value;
i++;
if (i < 25)
{
cin >> value;
}
}
n = i;
}
void Bubblesort(int ulist[26], int slist[26], int n)
{
int i, j, temp;
for (i = 0; i < n; i++)
slist[i] = ulist[i];
for (j = 25 - 1; j > 0; j--) //25 is Length of the array
for (i = 0; i < j; i++)
if (slist[i] > slist[i + 1])
{
temp = slist[i];
slist[i] = slist[i + 1];
slist[i + 1] = temp;
}
}
void print(int list[26], int n)
{
int i;
cout << " list of numbers are : \n";
for (i = 0; i < n; ++i)
{
cout << list[i] << '\n';
}
cout << "\n\n";
}
void reversesort(int slist[26], int n) //checked w online compiler, works
{
cout << "List of numbers in descending order is: \n";
for (int i = n - 1; i >= 0; --i)
cout << slist[i] << ", ";
cout << "\n";
}
I'm assuming this is some sort of memory problem and that the source of this has to do with passing slist, which was modified in the bubblesort function, through the functions I wrote. I'm pretty new to C++ (coming from python) so I'm assuming I'm missing something as far as passing arrays to functions is concerned.
EDIT: I guess to sum everything up - how can I take the data inputted in the input function and use that array in another function? And how can I take the array that has been sorted by the bubblesort function and use that array in another function?
The first instance of undefined behavior in your code is
if (slist[i] > slist[i + 1])
in Bubblesort.
Due to
for (j = 25 - 1; j > 0; j--)
for (i = 0; i < j; i++)
the maximum index accessed by this loop is slist[24] (24 from i + 1 where i < j and j = 25 - 1 = 24, so i = 23).
Your input is only 4 numbers, so only slist[0] through slist[3] are initialized. The remaining elements (slist[4] through slist[25]) are uninitialized. Reading from an uninitialized variable has undefined behavior.

FirstChance Exception StackOverFlow Merge Sort Shell Sort Bubble Sort

Hey guys I'm working on some sorts and am trying to implement a bubble sort, a merge sort, and a shell sort. I use an outdated technique but I was wondering if you guys could let me know why I keep getting the following error:
First-chance exception at 0x01135EF7 in sortApplication2.exe: 0xC00000FD: Stack overflow (parameters: 0x00000000, 0x00542000).
Unhandled exception at 0x01135EF7 in sortApplication2.exe: 0xC00000FD: Stack overflow (parameters: 0x00000000, 0x00542000).
I am using Visual Studio 2012 if that plays any part. My code is in three different files so I'll post each separately.
My header file:
#pragma once
class sort
{
public:
sort();
void random1(int array[]);
void random2(int array[]);
void random3(int array[]);
void bubbleSort(int array[], int length);
/*void merge(int *input, int p, int r);
void merge_sort(int *input, int p, int r);*/
void shellSort(int array[], int length);
};
My class implementation file:
#include "sort.h"
#include <time.h>
#include <iostream>
using namespace std;
sort::sort()
{}
void sort::random1(int array[])
{
// Seed the random-number generator with current time so that
// the numbers will be different every time the program runs.
for(int i = 0; i < 25; i++)
{
srand ((unsigned) time(NULL));
int n = rand(); //generates a random number
array[i] = n; //places it into the array
}
}
void sort::random2(int array[])
{
// Seed the random-number generator with current time so that
// the numbers will be different every time the program runs.
for(int i = 0; i < 10000; i++)
{
srand ((unsigned) time(NULL));
int n = rand(); //generates a random number
array[i] = n; //places it into the array
}
}
void sort::random3(int array[])
{
// Seed the random-number generator with current time so that
// the numbers will be different every time the program runs.
for(int i = 0; i < 100000; i++)
{
srand ((unsigned) time(NULL));
int n = rand(); //generates a random number
array[i] = n; //places it into the array
}
}
void sort::bubbleSort(int array[], int length)
{
//Bubble sort function
int i,j;
for(i = 0; i < 10; i++)
{
for(j = 0; j < i; j++)
{
if(array[i] > array[j])
{
int temp = array[i]; //swap
array[i] = array[j];
array[j] = temp;
}
}
}
}
/*void sort::merge(int* input, int p, int r) //the merge algorithm of the merge sort
{
int mid = (p + r) / 2;
int i1 = 0;
int i2 = p;
int i3 = mid + 1;
// Temp array
int x = r -p + 1;
int *temp;
temp = new int [x];
// Merge in sorted form the 2 arrays
while ( i2 <= mid && i3 <= r )
if ( input[i2] < input[i3] )
temp[i1++] = input[i2++];
else
temp[i1++] = input[i3++];
// Merge the remaining elements in left array
while ( i2 <= mid )
temp[i1++] = input[i2++];
// Merge the remaining elements in right array
while ( i3 <= r )
temp[i1++] = input[i3++];
// Move from temp array to master array
for ( int i = p; i <= r; i++ )
input[i] = temp[i-p];
}
void sort::merge_sort(int *input, int p, int r) //the merge sort algorithm
{
if ( p < r ) //When p and r are equal the recursion stops and the arrays are then passed to the merge function.
{
int mid = (p + r) / 2;
merge_sort(input, p, mid); //recursively calling the sort function in order to break the arrays down as far as possible
merge_sort(input, mid + 1, r);//recursively calling the sort function in order to break the arrays down as far as possible
merge(input, p, r); //merge function realigns the smaller arrays into bigger arrays until they are all one array again
}
}*/
void sort::shellSort(int array[], int length) //Shell sort algorithm
{
int gap, i, j, temp;
for( gap = length / 2; gap > 0; gap /= 2) //gap is the number of variables to skip when doing the comparisons
{
for( i = gap; i < length; i++) //This for loop sets the variable to use as the gap for the comparisons
{
for (j = i - gap; j >= 0 && array[j] > array[j + gap]; j -= gap)
{
temp = array[j]; //the array variables are swapped
array[j] = array[j + gap];
array[j + gap] = temp;
}
}
}
}
And my driver file:
#include "sort.h"
#include <iostream>
using namespace std;
int main()
{
int bubbleArray1[25]; //these are the arrays to be sorted. three for each sort. each has a length of 25, 10000, or 100000.
int bubbleArray2[10000];
int bubbleArray3[100000];
int mergeArray1[25];
int mergeArray2[10000];
int mergeArray3[100000];
int shellArray1[25];
int shellArray2[10000];
int shellArray3[100000];
sort Sorts;
Sorts.random1(bubbleArray1);
Sorts.random1(mergeArray1);
Sorts.random1(shellArray1);
Sorts.random2(bubbleArray2);
Sorts.random2(mergeArray2);
Sorts.random2(shellArray2);
Sorts.random3(bubbleArray3);
Sorts.random3(mergeArray3);
Sorts.random3(shellArray3);
cout << "BubbleSort1 is now being sorted.\n";
Sorts.bubbleSort(bubbleArray1, 25);
cout << "BubbleSort2 is now being sorted.\n";
Sorts.bubbleSort(bubbleArray2, 10000);
cout << "BubbleSort3 is now being sorted.\n";
Sorts.bubbleSort(bubbleArray3, 100000);
cout << "End bubble sorts.\n";
/*cout << "MergeSort1 is now being sorted.\n";
Sorts.merge_sort(mergeArray1, 0, 25);
cout << "MergeSort2 is now being sorted.\n";
Sorts.merge_sort(mergeArray2, 0, 10000);
cout << "MergeSort3 is now being sorted.\n";
Sorts.merge_sort(mergeArray3, 0, 100000);
cout << "End merge sorts.\n";*/
cout << "ShellSort1 is now being sorted.\n";
Sorts.shellSort(shellArray1, 25);
cout << "ShellSort1 is now being sorted.\n";
Sorts.shellSort(shellArray2, 10000);
cout << "ShellSort1 is now being sorted.\n";
Sorts.shellSort(shellArray3, 100000);
cout << "End shell sorts.\n";
cout << "Array\tElements\n";
cout << "BubbleSort1\t";
for(int i = 0; i < 25; i++)
{
cout << bubbleArray1[i] << " ";
}
cout << "\nMergeArray1\t";
for(int i = 0; i < 25; i++)
{
cout << mergeArray1[i] << " ";
}
cout << "\nShellArray1\t";
for(int i = 0; i < 25; i++)
{
cout << shellArray1[i] << " ";
}
return 0;
}
I know it's a lot of code. And there are probably many ways I could make the code better.
I would just like to know what's causing the error up above since I can't find it using my compiler.
You are allocating too much memory on the stack. Variables with 'automatic' storage class go on the stack. Allocate heap instead.
So, instead of:
int shellArray3[100000];
Do:
int* shellArray3 = new int[100000];
Or better yet, use std::vector.
If you don't want to use heap memory, you could also use the static storage class for something like this. To do that:
static int shellArray3[100000];
That will allocate one instance of the variable for the whole program rather than allocating a copy for each function entry on the stack.

Heap Sort in C++

Okay, so after struggling with trying to debug this, I have finally given up. I'm a beginner in C++ & Data Structures and I'm trying to implement Heap Sort in C++. The code that follows gives correct output on positive integers, but seems to fail when I try to enter a few negative integers.
Please point out ANY errors/discrepancies in the following code. Also, any other suggestions/criticism pertaining to the subject will be gladly appreciated.
//Heap Sort
#include <iostream.h>
#include <conio.h>
int a[50],n,hs;
void swap(int &x,int &y)
{
int temp=x;
x=y;
y=temp;
}
void heapify(int x)
{
int left=(2*x);
int right=(2*x)+1;
int large;
if((left<=hs)&&(a[left]>a[x]))
{
large=left;
}
else
{
large=x;
}
if((right<=hs)&&(a[right]>a[large]))
{
large=right;
}
if(x!=large)
{
swap(a[x],a[large]);
heapify(large);
}
}
void BuildMaxHeap()
{
for(int i=n/2;i>0;i--)
{
heapify(i);
}
}
void HeapSort()
{
BuildMaxHeap();
hs=n;
for(int i=hs;i>1;i--)
{
swap(a[1],a[i]);
hs--;
heapify(1);
}
}
void main()
{
int i;
clrscr();
cout<<"Enter length:\t";
cin>>n;
cout<<endl<<"Enter elements:\n";
for(i=1;i<=n;i++) //Read Array
{
cin>>a[i];
}
HeapSort();
cout<<endl<<"Sorted elements:\n";
for(i=1;i<=n;i++) //Print Sorted Array
{
cout<<a[i];
if(i!=n)
{
cout<<"\t";
}
}
getch();
}
I've been reading up on Heap Sort but I'm not able to grasp most of the concept, and without that I'm not quite able to fix the logical error(s) above.
You set hs after calling BuildMaxHeap. Switch those two lines.
hs=n;
BuildMaxHeap();
When I implemented my own heapsort, I had to be extra careful about the indices; if you index from 0, children are 2x+1 and 2x+2, when you index from 1, children are 2x and 2x+1. There were a lot of silent problems because of that. Also, every operation needs a single well-written siftDown function, that is vital.
Open up Wikipedia at the Heapsort and Binary heap articles and try to rewrite it more cleanly, following terminology and notation where possible. Here is my implementation as well, perhaps it can help.
Hmmm now that I checked your code better, are you sure your siftDown/heapify function restricts sifting to the current size of the heap?
Edit: Found the problem! You do not initialize hs to n before calling BuildMaxHeap().
I suspect it's because you're 1-basing the array. There's probably a case where you're accidentally 0-basing it but I can't spot it in the code offhand.
Here's an example if it helps.
#include <iostream>
#include <vector>
using namespace std;
void max_heapify(std::vector<int>& arr, int index, int N) {
// get the left and right index
int left_index = 2*index + 1;
int right_index = 2*index + 2;
int largest = 0;
if (left_index < N && arr[left_index] > arr[index]) {
// the value at the left_index is larger than the
// value at the index of the array
largest = left_index;
} else {
largest = index;
}
if (right_index < N && arr[right_index] > arr[largest]) {
// the value at the right_index is larger than the
// value at the index of the array
largest = right_index;
}
// check if largest is still the index, if not swap
if (index != largest) {
// swap the value at index with value at largest
int temp = arr[largest];
arr[largest] = arr[index];
arr[index] = temp;
// once swap is done, do max_heapify on the index
max_heapify(arr, largest, N);
}
}
void build_max_heap(std::vector<int>& arr, int N) {
// select all the non-leaf except the root and max_heapify them
for (int i = N/2 - 1; i >= 0; --i) {
max_heapify(arr, i, N);
}
}
void heap_sort(std::vector<int>& arr) {
int N = arr.size();
int heap_size = N;
// build the max heap
build_max_heap(arr, N);
// once max heap is built,
// to sort swap the value at root and last index
for (int i = N - 1; i > 0; --i) {
// swap the elements
int root = arr[0];
arr[0] = arr[i];
arr[i] = root;
// remove the last node
--heap_size;
// perform max_heapify on updated heap with the index of the root
max_heapify(arr, 0, heap_size);
}
}
int main() {
std::vector<int> data = {5,1,8,3,4,9,10};
// create max heap from the array
heap_sort(data);
for (int i : data) {
cout << i << " ";
}
return 0;
}
# include <iostream> //Desouky//
using namespace std;
void reheapify(int *arr, int n, int i)
{
int parent = i; // initilaize largest as parent/root
int child1 = 2 * i + 1; // to get first chid
int child2 = 2 * i + 2; // to get second child
if (child1 < n && arr[child1] > arr[parent]) // if child2 > parent
{
parent = child1;
}
//if child > the parent
if (child2 < n && arr[child2] > arr[parent])
{
parent = child2;
}
// if the largest not the parent
if (parent != i)
{
swap(arr[i], arr[parent]);
// Recursively heapify the affected sub-tree
reheapify(arr, n, parent);
}
}
void heapsort(int *arr, int n)
{
// build a heap
for (int i = n - 1; i >= 0; i--)
{
reheapify(arr, n, i);
}
// One by one extract an element from heap
for (int i = n - 1; i >= 0; i--)
{
// Move current root to end
swap(arr[0], arr[i]);
// call max heapify on the reduced heap
reheapify(arr, i, 0);
}
}
int main()
{
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
int n;
cin >> n;
int* arr = new int[n];
for (int i = 0; i < n; i++)
{
cin >> arr[i];
}
heapsort(arr, n);
for (int i = 0; i < n; i++)
{
cout << arr[i] << " ";
}
}