selection sort using recursion - c++

void swap(int a[], int x, int y)
{
int temp = a[x];
a[x] = a[y];
a[y] = temp;
}
void sort(int arr[], int x)
{
static int count = 0;
if (x == 1)
{
return;
}
int min = 100; // random value
int index;
for (int i = 0; i < x; i++)
{
if (arr[i] < min)
{
min = arr[i];
index = i;
}
}
swap(arr, count, index);
count++;
sort(arr + 1, x - 1);
}
int main()
{
int x;
cin >> x;
int A[x];
for (int i = 0; i < x; i++)
{
cin >> A[i];
}
sort(A, x);
for (int i = 0; i < x; i++)
{
cout << A[i] << " ";
}
cout << endl;
return 0;
}
this code is of selection sort using recursion. It is printing garbage values. what's the mistake in this. i am not sure but i guess because of using the static variable in the sort function(). it is printing garbage values

Replace swap(arr, count, index); with
swap(arr, 0, index);
and remove static int count = 0;.
Replace sort(A, x); in the main with
sort(A, x - 1);
and change the condition if (x == 1) to if (x == 0).
I suggest to rename index to last.
Replace min = 100; with
min = arr[0];

For starters variable length arrays like this
int x;
cin >> x;
int A[x];
is not a standard C++ feature.
Nevertheless the function can invoke undefined behavior when for example is called with the second parameter equal to 0.
Also there is no sense to declare the static variable.
The function will not sort an array elements of which have values greater than 100.
The variable index must be initialized to 0 before the for loop.
Also there is already the standard function std::swap that swaps two objects.
The function can be defined the following way
#include <algorithm>
void selection_sort( int a[], size_t n )
{
if ( not ( n < 2 ) )
{
auto it = std::min_element( a, a + n );
if ( it != a ) std::iter_swap( a, it );
selection_sort( a + 1, n - 1 );
}
}
If you do not know yet standard algorithms then the functions can look the following way
void swap( int &a, int &b )
{
int rmp = a;
a = b;
b = tmp;
}
void selection_sort( int a[], size_t n )
{
if ( not ( n < 2 ) )
{
size_t index = 0;
for ( size_t i = 1; i < n; i++ )
{
if ( a[i] < a[index] ) index = i;
}
if ( index != 0 ) swap( a[0], a[index] );
selection_sort( a + 1, n - 1 );
}
}

One of the easy ways of doing the selection sort using recursion is as follows:
#include<iostream>
using namespace std;
void selectionSort(int *arr, int size,int minIndex){
//base case
if(size ==0 || size ==1 || minIndex == size){
return;
}
//processing
for(int i=minIndex+1;i<size;i++){
if(arr[i]<arr[minIndex]){
swap(arr[minIndex], arr[i]);
}
}
//recursive call
selectionSort(arr,size,minIndex+1);
}
int main(){
int arr[7]={7,6,5,4,3,2,1};
int size = 7;
int minIndex = 0;
selectionSort(arr,size,minIndex);
for(int i=0;i<7;i++){
cout<<arr[i]<<" ";
}
}
We are creating a minIndex at the starting of the array and comparing it with the values in the remaining array, to get the minimum value of the whole array on the left-most side. At each recursive call, we will increment the place of minIndex for further comparison. Hope this helps.

a=[6,5,4,3,2,1,0,-1]
length=a.length
cur=0
n=cur+1
function fun(n)
{
if(cur==length-1)
{
return a
}
else if(a[cur]>a[n])
{
temp=a[cur]
a[cur]=a[n]
a[n]=temp
if(n==length-1)
{
n=cur
cur++
}
// console.log(a)
// console.log(cur)
return fun(n+1)
}
else
{
if(n==length-1)
{
n=cur
cur++
}
return fun(n+1)
}
}
let t=[]
t=[...fun(n)]
console.log(t)

Related

Getting different output on each execution

I tried to implement number of inversions in an array, using merge sort.
Every time I execute this code, I get different value of the number of inversions. I am not able to figure out the reason for this. Please have a look at the code and tell me the mistake.
#include<stdio.h>
#include<iostream>
using namespace std;
int count =0;
void merge(int A[],int start,int mid,int end)
{
int size1 = mid-start+1;
int size2 = end-(mid+1)+1;
int P[size1];
int Q[size2];
for(int i=0;i<size1;i++)
P[i]=A[start+i];
for(int j=0;j<size2;j++)
Q[j]=A[mid+j+1];
int k = 0;
int l = 0;
int i =0;
while(k<mid && l<end)
{
if(P[k]>Q[l])
{
A[i] = Q[l];
l++; i++;
count++;
}
else
{
A[i] = P[k];
k++; i++;
}
}
}
void inversions(int A[],int start,int end)
{
if(start!=end)
{
int mid = (start+end)/2;
inversions(A,start,mid);
inversions(A,mid+1,end);
merge(A,start,mid,end);
}
}
int main()
{
int arr[] = {4,3,1,2,7,5,8};
int n = (sizeof(arr) / sizeof(int));
inversions(arr,0,n-1);
cout<<"The number of inversions is:: "<<count<<endl;
return 0;
}
int k = 0;
int l = 0;
int i =0;
while(k<mid && l<end)
{
if(P[k]>Q[l])
{
A[i] = Q[l];
l++; i++;
count++;
}
else
{
A[i] = P[k];
k++; i++;
}
}
Few mistakes here, i starts from start and not 0. k must loop from 0 till size1 and not till mid. Similarly, l must loop from 0 till size2 and not till end. You are incrementing count by 1 when P[k] > Q[l] but this is incorrect. Notice that all the elements in array P following the element P[k] are greater than Q[l]. Hence they also will form an inverted pair. So you should increment count by size1-k.
Also, the merge procedure should not only count the inversions but also merge the two sorted sequences P and Q into A. The first while loop while(k<size1 && l<size2) will break when either k equals size1 or when l equals size2. Therefore you must make sure to copy the rest of the other sequence as it is back into A.
I have made the appropriate changes in merge and pasted it below.
void merge(int A[],int start,int mid,int end)
{
int size1 = mid-start+1;
int size2 = end-(mid+1)+1;
int P[size1];
int Q[size2];
for(int i=0;i<size1;i++)
P[i]=A[start+i];
for(int j=0;j<size2;j++)
Q[j]=A[mid+j+1];
int k = 0;
int l = 0;
int i = start;
while(k<size1 && l<size2)
{
if(P[k]>Q[l])
{
A[i] = Q[l];
l++; i++;
count += size1-k;
}
else
{
A[i] = P[k];
k++; i++;
}
}
while (k < size1)
{
A[i] = P[k];
++i, ++k;
}
while (l < size2)
{
A[i] = Q[l];
++i, ++l;
}
}
int P[size1];
int Q[size2];
VLA (Variable length arrays) are not supported by C++. size1 and size2 are unknown during compile time. So, each time they get a different value and hence the difference in output.
Use std::vector instead
std::vector<int> P(size1, 0); //initialize with size1 size
std::vector<int> Q(size2, 0); //initialize with size2 size

kth smallest element using min-heap

I was solving a problem of kth smallest element using min-heap but got stuck as it's always giving me the first smallest element, so I guess my extractmin function is not working correctly.My approach was to make array into a min heap data structure in which root is the minimum element and then remove k-1 smallest elements and then simply return the value of root.
#include <iostream>
using namespace std;
void swap(int &x, int &y)
{
int u = x;
x = y;
y = u;
}
int l(int p)
{
return 2 * p + 1;
}
int r(int p)
{
return 2 * p + 2;
}
void heapify(int arr[], int i, int n);
void makeheap(int arr[], int n)
{
int last = n - 1;
for (int i = (last - 1) / 2; i >= 0; i--)
{
heapify(arr, i, n);
}
}
void heapify(int arr[], int i, int n)
{
int smallest = arr[i],y=0;
if (l(i) <= n - 1 && arr[l(i)] < arr[i])
{
smallest = arr[l(i)];
}
if (r(i) <= n - 1 && arr[r(i)] < smallest)
{
smallest = arr[r(i)];
y=1;
}
if (smallest != arr[i])
{
if(y==0){
swap(arr[l(i)], arr[i]);}
else if(y==1)
{
swap(arr[r(i)],arr[i]);
}
heapify(arr, i, n);
}
}
void extractmin(int arr[], int &n)
{
swap(arr[0], arr[n - 1]);
n--;
heapify(arr, 0, n);
}
int getmin(int arr[])
{
return arr[0];
}
int main()
{
int T;
cin >> T;
while (T--)
{
int n;
cin >> n;
int arr[n];
for (int i = 0; i < n; i++)
{
cin >> arr[i];
}
int k;
cin >> k;
makeheap(arr, n);
for (int i = 0; i < k - 1; i++) {
extractmin(arr, n);
}
cout << getmin(arr) << "\n";
}
}
Input:
2
6
7 10 4 3 20 15
3
5
7 10 4 20 15
4
Expected Output:
7
15
My Output:
3
4
In heapify() you use
swap(smallest,arr[i]);
That exchanges the values in smallest and arr[i]. But arr[l(i)] or arr[r(i)] is not changed. What this actually does is copy the smaller value of arr[l(i)] and arr[r(i)] into arr[i].
Also in main you do
for (int i = 0; i < k - 1; i--) {
which counts i down till it hits INT_MIN instead of counting up to k. This quickly causes the heap to be empty and the code to segfault.
PS: Why not use the std::make_heap and friends?

Find all possible arrays of size n constructed with all possible combinations of elements from another array in all possible orders?

For an array A of arbitrary length n, I'd like to fill in a n x m array B with all combination of elements from A that includes all possible orders of those elements. For example, if A = {1, 2, 3} and m = 2, I'd like to get B as:
11
12
13
21
22
23
31
32
33
What is an efficient way to do this in C/C++? Thanks!
EDIT: Here is what I figured out to work (data is within the class combs which is basically a matrix class with some added tricks):
void combs::setCombs (int arr[], int n, int m) {
int z, tmp, repeat;
int max = (int (pow(double (n), double( m ))));
for (int i = 0; i < m; i++) {
z = 0;
repeat = int (pow( double (n), double (i)));
for (int j = 0; j < repeat; j++) {
for (int k = 0; k < n; k ++) {
for (int p = 0; p < max/(n*repeat); p ++) {
cout << arr[k] << endl;
data[z*ROWS + i] = arr[k];
z++;
}
}
}
}
}
As mentioned by #Joachim Pileborg your question lacks a lot in the way of parameters.But lets say you could guarantee that you were passing me a vector of SORTED UNIQUE ints. Then this brute force would be possible:
std::vector< std::string > Combo( const std::vector< char >& source, int m )
{
std::vector< std::vector< char >::const_iterator > digits( length, source.cbegin() );
std::vector< std::string > result( source.size() * m );
for( int i = 0; i < result.size(); i++ )
{
for( int j = 0; j < m; j++ )
{
result[i] += *(digits[j]);
}
for( int j = digits.size() - 1; j >= 0; j-- )
{
++digits[j];
if( digits[j] == source.cend() )
{
digits[j] = source.cbegin();
}
else
{
break;
}
}
}
return result;
}
What you are describing sounds like partial permutations, not combinations.
If you are using c++, then it is recommended to use vectors, because vectors can tell you their size, and they free their own memory. An implementation with vectors would be as follows:
vector<vector<int> > partialPermutations(vector<int> &A,int m){
int i,i2,t,n=A.size(),total=1;
for(i=0;i<m;i++) total*=n;
vector<vector<int> > result;
for(i=0;i<total;i++){
result.push_back(vector<int>());
t=i;
for(i2=0;i2<m;i2++){
result[i].push_back(A[t%n]);
t/=n;
}
}
return result;
}
int main() {
vector<int> A;
int total,i,i2;
for(i=1;i<=4;i++) A.push_back(i);
vector<vector<int> > re=partialPermutations(A,2);
for(i=0;i<re.size();i++){
for(i2=0;i2<2;i2++)
cout<<re[i][i2]<<" ";
cout<<endl;
}
return 0;
}
If you still want to use arrays, then the code would be as follows:
int** partialPermutations(int*A,int n,int m,int &total){
int i,i2,t;
total=1;
for(i=0;i<m;i++) total*=n;
int **result=new int*[total];
for(i=0;i<total;i++){
t=i;
result[i]=new int[m];
for(i2=0;i2<m;i2++){
result[i][i2]=A[t%n];
t/=n;
}
}
return result;
}
int main() {
int A[]={1,2,3,4};
int total,i,i2;
int **re=partialPermutations(A,4,2,total);
for(i=0;i<total;i++){
for(i2=0;i2<2;i2++)
cout<<re[i][i2]<<" ";
cout<<endl;
}
//Cleanup
for(i=0;i<total;i++) delete[] re[i];
delete[] re;
return 0;
}
Notice that by using arrays, we have to recover the size of the resulting array (passing total by reference), and we have to free the memory afterwards. None of this is needed with vectors.
#include<iostream>
using namespace std;
void printStrRec(string s,string ans,int k,int i)
{
if(i==k)
{
cout<<"\nAnswer : "<<ans<<endl;
}
else
{
for(int x=0;x<s.size();++x)
{
ans[i]=s[x];
printStrRec(s,ans,k,i+1);
}
}
}
void printStrings(string s,int k)
{
string ans;
for(int p=0;p<k;++p)
{
ans+="x";
}
printStrRec(s,ans,k,0);
}
int main()
{
int k;
string s;
cout<<"Enter the set : ";
cin>>s;
cout<<"\nEnter k : ";
cin>>k;
printStrings(s,k);
return 0;
}
Hope that helps.

Error using Insertion Sort algorithm - array is not sorted exactly.

Here is some working code that implements a modified version of the Quicksort algorithm that uses Insertion Sort for array size n > 8. My test array isn't sorting exactly right, and I think it must be with my implementation of Insertionsort and Insert.
The general form of the recursive Insertionsort algorithm is:
void Insertionsort(int S[], int n)
{
if(n>1)
Insertionsort(S,n-1);
Insert(S,n-1);
}
void Insert(int *S, int k)
{
int key = S[k];
int j = k-1;
while(j>=0 && S[j] > key)
{
S[j+1] = S[j];
j--;
}
S[j+1] = key;
}
Here is my complete working code that does not sort quite exactly right:
#include <iostream>
#include <string>
#include <stdlib.h>
using namespace std;
int comparisons = 0;
int compare_qs_m3_ins[12];
// Function prototypes
int partition(int *S,int l, int u);
void exchange(int list[], int p, int q);
void Insert(int S[], int k);
void Insertionsort(int S[], int low, int hi);
void Quicksort_Insert_M3(int S[], int n, int p, int r);
int main()
{
srand (time(NULL));
// Declare all arrays used for testing
int S1_500[500];
int S2_500[500];
int S3_500[500];
int S1_300[300];
int S2_300[300];
int S3_300[300];
int S1_100[100];
int S2_100[100];
int S3_100[100];
int S1_8[8];
int S2_8[8];
int S3_8[8];
// Fill arrays with random integers
for(int i=0; i<500; i++)
{
S1_500[i] = rand()%1000;
S2_500[i] = rand()%1000;
S3_500[i] = rand()%1000;
}
for(int i=0; i<300; i++)
{
S1_300[i] = rand()%1000;
S2_300[i] = rand()%1000;
S3_300[i] = rand()%1000;
}
for(int i=0; i<100; i++)
{
S1_100[i] = rand()%500;
S2_100[i] = rand()%500;
S3_100[i] = rand()%500;
}
for(int i=0; i<8; i++)
{
S1_8[i] = rand()%100;
S2_8[i] = rand()%100;
S3_8[i] = rand()%100;
}
Quicksort_Insert_M3(S1_500,500,0,499);
compare_qs_m3_ins[0] = comparisons;
comparisons = 0;
Quicksort_Insert_M3(S2_500,500,0,499);
compare_qs_m3_ins[1] = comparisons;
comparisons = 0;
Quicksort_Insert_M3(S3_500,500,0,499);
compare_qs_m3_ins[2] = comparisons;
comparisons = 0;
Quicksort_Insert_M3(S1_300,300,0,299);
compare_qs_m3_ins[3] = comparisons;
comparisons = 0;
Quicksort_Insert_M3(S2_300,300,0,299);
compare_qs_m3_ins[4] = comparisons;
comparisons = 0;
Quicksort_Insert_M3(S3_300,300,0,299);
compare_qs_m3_ins[5] = comparisons;
comparisons = 0;
Quicksort_Insert_M3(S1_100,100,0,99);
compare_qs_m3_ins[6] = comparisons;
comparisons = 0;
Quicksort_Insert_M3(S2_100,100,0,99);
compare_qs_m3_ins[7] = comparisons;
comparisons = 0;
Quicksort_Insert_M3(S3_100,100,0,99);
compare_qs_m3_ins[8] = comparisons;
comparisons = 0;
Quicksort_Insert_M3(S1_8,8,0,7);
compare_qs_m3_ins[9] = comparisons;
comparisons = 0;
Quicksort_Insert_M3(S2_8,8,0,7);
compare_qs_m3_ins[10] = comparisons;
comparisons = 0;
Quicksort_Insert_M3(S3_8,8,0,7);
compare_qs_m3_ins[11] = comparisons;
comparisons = 0;
//for(int i=0; i<12; i++)
//cout << compare_qs_m3_ins[i] << endl;
for(int i=0;i<499;i++)
cout << S1_500[i] << endl;
}
int partition(int *S,int l, int u)
{
int x = S[l];
int j = l;
for(int i=l+1; i<=u; i++)
{
comparisons++;
if(S[i] < x)
{
j++;
swap(S[i],S[j]);
}
}
int p = j;
swap(S[l],S[p]);
return p;
}
void swap(int &val1, int &val2)
{
int temp = val1;
val1 = val2;
val2 = temp;
}
void exchange(int list[], int p, int q)
{
int temp = list[p];
list[p] = list[q];
list[q] = temp;
}
int Sort3(int list[], int p, int r)
{
int median = (p + r) / 2;
comparisons++;
if(list[p] <= list[median])
{
comparisons++;
if(list[median]>list[r])
{
comparisons++;
if(list[p]<list[r])
{
int temp = list[p];
list[p] = list[r];
list[r] = list[median];
list[median] = temp;
}
else
{
exchange(list,median,r);
}
}
else
;
}
else
{
comparisons++;
if(list[p] > list[r])
{
comparisons++;
if(list[median] < list[r])
{
int temp = list[p];
list[p] = list[median];
list[median] = list[r];
list[r] = temp;
}
else
{
exchange(list,p,r);
}
}
else
{
exchange(list,p,median);
}
}
return list[r];
}
void Insert(int *S, int k)
{
int key = S[k];
int j = k-1;
while(j>=0 && S[j] > key)
{
S[j+1] = S[j];
j--;
comparisons++;
}
comparisons++;
S[j+1] = key;
}
void Insertionsort(int S[], int low, int hi)
{
if((hi-low)+1>1)
Insertionsort(S,low+1,hi);
Insert(S,hi-low);
}
void Quicksort_Insert_M3(int S[], int n, int low, int hi)
{
if((hi-low)<=8)
Insertionsort(S,low,hi);
else
{
if(low < hi)
{
if((low+1) == hi)
{
comparisons++;
if(S[low] > S[hi])
swap(S[low],S[hi]);
}
else
{
Sort3(S,low,hi);
if((low+2)<hi)
{
swap(S[low+1],S[(low+hi)/2]);
int q = partition(S, low+1, hi-1);
Quicksort_Insert_M3(S, n, low, q-1);
Quicksort_Insert_M3(S, n, q+1, hi);
}
}
}
}
}
The function supposed to sort three array elements in ascending order doesn't:
int Sort3(int list[], int p, int r)
{
called only for p + 2 <= r, so
int median = (p + r) / 2;
p < median < r here. Let a = list[p], b = list[median] and c = list[r].
comparisons++;
if(list[p] <= list[median])
{
comparisons++;
if(list[median]>list[r])
{
comparisons++;
if(list[p]<list[r])
{
So here we have a <= b, c < b and a < c, together a < c < b
int temp = list[p];
list[p] = list[r];
list[r] = list[median];
list[median] = temp;
but you place them in order c, a, b. Probably you intended to use if (list[r] < list[p]) there.
}
else
c <= a <= b
{
exchange(list,median,r);
so that arranges them in order a, c, b.
}
}
else
;
}
else
Here, b < a.
{
comparisons++;
if(list[p] > list[r])
{
c < a
comparisons++;
if(list[median] < list[r])
{
Then b < c < a
int temp = list[p];
list[p] = list[median];
list[median] = list[r];
list[r] = temp;
Yup, that's correct.
}
else
c <= b < a
{
exchange(list,p,r);
}
Okedoke.
}
else
{
b < a <= c
exchange(list,p,median);
Okay.
}
}
return list[r];
}
Why does this function return anything? You don't use the return value anyway.
"The general form of the recursive Insertionsort algorithm is" - if you need to have a head-recursive algorithm, yes, otherwise a better version is:
void Insertionsort(int S[], int i, int n)
{
Insert(S, i, n);
if(i < n)
Insertionsort(S, i+1, n);
}
which is much more understandable. Also, you might as well have put the body of Insert into Insertionsort.
I'm not going to try and figure out your overly complicated version of quicksort. A decent quicksort is around 20 lines or less (like this - www.algolist.net/Algorithms/Sorting/Quicksort) (and add another 10 or less for insertion sort). I suggest getting a better understanding by looking at another implementation and rewriting yours.
I believe this could've been asked as an extension of your previous question.

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] << " ";
}
}