In the following code, the result is ok, but the code will be crash when executing finish, and increase one error: Heap corruption detected, the free list is damaged at 0x600000008f50
int *mergeSort(int *a,int count) {
int leftCount = count / 2;
int rightCount = count - leftCount;
int *leftData = getData(a, 0, leftCount);
int *rightData = getData(a, leftCount, count);
int *sortedLeftData = mergeSort(leftData, leftCount);
int *sortedRightData = mergeSort(rightData, rightCount);
int *resultData = mergeData(sortedLeftData, sortedRightData, leftCount,
rightCount);
return resultData;
}
int *getData(int *a,int from, int to) {
if (from > to) { return nil; }
int *res = malloc(to - from + 1);
for (int index = from; index < to; index ++) {
int value = a[index];
res[index-from] = value;
}
return res;
}
int *mergeData(int *a, int *b, int acount, int bcount) {
int *result = malloc(acount + bcount);
int aindex,bindex,rindex;
aindex = bindex = rindex = 0;
while (aindex < acount | bindex < bcount) {
int value,avalue = INT_MAX,bvalue = INT_MAX;
if (aindex < acount) { avalue = a[aindex]; }
if (bindex < bcount) { bvalue = b[bindex]; }
// get value from a point.
if (avalue <= bvalue) {
value = avalue;
aindex ++;
}else {
// get value from b point.
value = bvalue;
bindex ++;
}
result[rindex] = value;
rindex ++;
}
return result;
}
I don't understand why does crash when free the point, any answer will helpfull, thanks.
All of your allocations are too small, and thus you are overflowing your buffers.
The malloc function allocates the requested number of bytes. You need to multiply the number of elements you require by sizeof(int) if your elements are int type. e.g.
int *result = malloc((acount + bcount) * sizeof(int));
Other potential problems I spotted while reading your code are:
Using the bitwise-or operator instead of logical-or:
while (aindex < acount | bindex < bcount)
// ^ should be ||
You never free your temporary buffers, thus your program will blow out memory by leaking like crazy. You must free leftData, rightData, sortedLeftData and sortedRightData in the mergeSort function after you are finished with them.
Note that merge sort actually does not require so much allocation. Doing so will have a huge impact on performance. An efficient implementation only requires a single additional buffer for scratch operations, which can be allocated at the beginning.
I did implementation merge sort use single buffer, as the following code:
void mergeSort(int *a, int count) {
int *tempBuffer = malloc(count * sizeof(int));
mergeSortWithBuffer(a, 0, 0, count - 1,tempBuffer);
free(tempBuffer);
}
void mergeSortWithBuffer(int *a, int leftStart, int rightStart, int end, int *tempBuffer) {
int leftCount = rightStart - leftStart;
int rightCount = end - rightStart + 1;
if (leftCount + rightCount <= 1) { return; }
if (leftCount != 0) {
// left dichotomy
int lls = leftStart;
int lrs = leftStart + leftCount/2;
int lnd = rightStart - 1;
mergeSortWithBuffer(a, lls, lrs, lnd,tempBuffer);
}
if (rightCount != 0) {
// right dichotomy
int rls = rightStart;
int rrs = rightStart + rightCount/2;
int rnd = end;
mergeSortWithBuffer(a, rls, rrs, rnd,tempBuffer);
}
mergeData(a, leftStart, rightStart, end, tempBuffer);
}
void mergeData(int *a, int leftStart, int rightStart, int end,int *tempBuffer) {
int leftCount = rightStart - leftStart;
int rightCount = end - rightStart + 1;
int lindex,rindex;
lindex = rindex = 0;
while (lindex < leftCount || rindex < rightCount) {
int lv = INT_MAX,rv = INT_MAX;
if (lindex < leftCount) { lv = a[leftStart + lindex]; }
if (rindex < rightCount) { rv = a[rightStart + rindex]; }
if (lv <= rv) {
tempBuffer[leftStart + lindex + rindex] = lv;
lindex ++;
}else {
tempBuffer[leftStart + lindex + rindex] = rv;
rindex ++;
}
}
for (int index = 0; index < end - leftStart + 1; index ++) {
a[leftStart + index] = tempBuffer[leftStart + index];
}
}
I thought the mergeData function can replace data in the point a each other without the temp buffer, but the logic is too complex and the efficient is not fast, so i add the temp buffer in this function.
Would you have better suggestions if you have willing?
Related
I was trying to solve below problem:
Given two integer arrays nums1 and nums2, return an array of their intersection. Each element in the result must appear as many times as it shows in both arrays and you may return the result in any order.
Example 1:
Input: nums1 = [1,2,2,1], nums2 = [2,2]
Output: [2,2]
Here is my code:
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* intersect(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize){
for(int i=0; i<nums1Size-1; i++){
if(nums1[i]>nums1[i+1]){
int temp = nums1[i];
nums1[i] = nums1[i+1];
nums1[i+1] = temp;
i = -1;
}
}
for(int i=0; i<nums2Size-1; i++){
if(nums2[i]>nums2[i+1]){
int temp = nums2[i];
nums2[i] = nums2[i+1];
nums2[i+1] = temp;
i = -1;
}
}
int i = 0;
int j = 0;
int* res = (int*)malloc(10* sizeof(int));
int k = 0;
if(!(nums1Size > nums2Size)){
int * temp = nums1;
nums1 = nums2;
nums2 = temp;
int tempint = nums1Size;
nums1Size = nums2Size;
nums2Size = tempint;
}
while(i<nums1Size && j<nums2Size){
if(nums1[i] > nums2[j]){
j++;
}
else if(nums1[i] < nums2[j]){
i++;
}
else{
res[k++] = nums1[i];
i++; j++;
}
}
*returnSize = sizeof(res)/sizeof(res[0]);
return res;
}
To simplify the problem you have to solve, let's first write a helper function that counts the number of occurrences of a particular element inside an array:
int count_elem(int* arr, int n, int elem) {
int count = 0;
for (int i = 0; i < n; i += 1) {
if (arr[i] == elem) {
count += 1;
}
}
return count;
}
Now, let's try to solve the problem following the problem description:
int* intersect(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize) {
// here we allocate `res` with size of the biggest array, because that's the worst case we'll have
int* res = malloc(sizeof(int) * ((nums1Size > nums2Size) ? nums1Size : nums2Size));
// just to be sure `malloc()` did not return an error
if (res == NULL) {
return NULL;
}
// we'll keep track of how many elements we actually put inside `res`
*returnSize = 0;
// let's loop through all elements of `nums1`
for (int i = 0; i < nums1Size; i += 1) {
int elem = nums1[i];
// if we already put the element inside `res`, we skip this cycle
int count_res = count_elem(res, *returnSize, elem);
if (count_res > 0) {
continue;
}
// let's count the occurrences in both arrays
int count1 = count_elem(nums1, nums1Size, elem);
int count2 = count_elem(nums2, nums2Size, elem);
// let's calculate how many times the element must be present inside `res`
// i.e.: the same number of times of the array with the fewer occurrences of it
// NOTE: if `nums1` or `nums2` do not include the element, we also don't include it inside `res`
int count_min = (count1 < count2) ? count1 : count2;
// now let's put inside `res` as many times as we previously calculated
for (int i = 0; i < count_min; i += 1) {
res[*returnSize] = elem;
*returnSize += 1;
}
}
return res;
}
Let's try if it works:
int main(void) {
int arr1[] = {1, 2, 2, 1};
int arr2[] = {2, 2};
int res_size;
int* res = intersect(arr1, sizeof(arr1) / sizeof(arr1[0]), arr2, sizeof(arr2) / sizeof(arr2[0]), &res_size);
// let's print the result of `intersect()`
for (int i = 0; i < res_size; i += 1) {
printf("%d\n", res[i]);
}
return 0;
}
Output:
2
2
NOTE: the function is not optimized for speed nor for memory efficiency. This will be left as an exercise for the reader.
UPDATE
The previous version of the answer was wrong (sorry again). Now it should be correct.
Im getting the error "invalid operands to binary + (have int* and int*)" and i don't know why It is throwing me this error. how would I go about adding the array elements of the 2 arrays. note both arrays are the same size.
int* complement2_add(int* first_complement2[], int* second_compelment[], int size){
int count = 0,remainder = 0, carryover = 0;
int* cAdd = (int*)malloc(size*sizeof(int));
for(count = size-1; count >= 0; count--){
remainder = first_complement2[count] + second_compelment[count] + carryover;
if(remainder == 1){
cAdd[count] = 1;
carryover = 0;
}
else if(remainder == 2){
cAdd[count] = 0;
carryover = 1;
}
else if(remainder == 3){
cAdd[count] = 1;
carryover = 1;
}
else if(remainder == 0){
cAdd[count] =0;
carryover = 0;
}
}
if(carryover == 1){
cAdd[count] = 1;
}
return cAdd;
}
Then I am calling the function in main like this.
int* add1 = complement_2_add(complement2Array1, complement2Array2, j);
Complement2Array1 and Complement2Array2 are defined the same.
int* complement2Array1 = signed2complement2(signedIntArray1, j);
and signed2complement2 is defined as.
int* signed2complement2(int signed_binary[], int size){
int i = 0;
int* complemt2Array = (int*)malloc(size*sizeof(int));
int flipflag = 0;
for(i = size-1; i>=0;i-- ){
if(flipflag == 0){
complemt2Array[i] = signed_binary[i];
if(signed_binary[i] == 1){
flipflag = 1;
}
}
else{
complemt2Array[i] = signed_binary[i] == 0?1:0;
}
}
return complemt2Array;
}
remainder = first_complement2[count] + second_compelment[count] + carryover;
In this first_complement2[count] , second_compelment[count] both are integer pointers .
As both first_complement and second_complement are array of integer pointers.
You need to dereference them before adding -
remainder = (*first_complement2[count]) + (*second_compelment[count]) + carryover;
EDIT
Didn't you got any warning or error for passing a int * to a function which expects array of integer pointer or int ** ?
int* complement2Array1 = signed2complement2(signedIntArray1, j); // it is an int *
complement2Array1 and complement2array2 has to be of type int ** or to be array of int pointers.
Or simple as #alk Sir suggested use int * instead of int **.
This
int* complement2_add(int* first_complement2[], int* second_compelment[], int size){
if equal to
int* complement2_add(int ** first_complement2, int ** second_compelment, int size){
which from the way you use first_complement2 and second_compelment and the way you call complement2_add() is wrong.
It seems you wanted
int* complement2_add(int * first_complement2, int * second_compelment, int size){
Also add the prototype to it before it is used:
int* complement2_add(int * first_complement2, int * second_compelment, int size);
... somefunc(...)
{
...
int* add1 = complement_2_add(complement2Array1, complement2Array2, j);
...
}
int* complement2_add(int* first_complement2, int* second_compelment, int size)
{
int count = 0,remainder = 0, carryover = 0;
...
Hi Guys i have edited the questions.Here is my entire code.I have given basic amount of readability to my program.I hope u guys can understand the program.
#include<stdio.h>
#include<stdlib.h>
int Max_Min(int,int,int,int *, int *);
int *Max,Number;
int main()
{
int n1, n2,Maximum_Element=0,*Max;
int i = 0, j = 0;
scanf("%d",&Number);
Max =(int *) malloc(sizeof(int)*Number);//Array Max is created
for (int k = 0;k <(Number/2);k++)
{
scanf("%d", &n1);
scanf("%d", &n2);
Max[k] = Max_Min(0,1,0,&n1,&n2);//Passing integer elements n1,n2 with flag 0
}
Maximum_Element=Max_Min(1,1,((sizeof(Max)*Number)/8),Max,Min);//Passing array elements Max,Min with flag 1 to function Max_Min
printf("Maximum_Element=%d", Maximum_Element);
return 0;
}
int Max_Min(int flag,int Max_Min_flag,int length,int *n1,int *n2)//n1 and n2 should be able to handle array and integers
{
int i=0,j = 0,k1,k2,Min1 = 0, Min2 = 0,count=0, Not_Zero = 0,x=0,y=0, *New_Max = 0,*New_Min;
/*Recursive Loop for splitting the array elements and calling the array */
if (flag == 1)
{
New_Max = (int *)(malloc(sizeof(int)*length));
for (;i <= ((length) / 2);i = i + 2)//
{
k1 = n1[i];
j = i + 1;
if (j <= ((length + 1) / 2))
{
k2 = n1[j];
New_Max[count] = Max_Min(0, 1, 0, &k1, &k2);//It is passing integer elements with flag 0 to function Max_Min
count++;
}
}
New_Max[count] = n1[j + 1];
for (int i = 0;i < count + 1;i++)
{
**/* Problem is assigning Max[i]=New_Max[i] is not getting assigned*/**
Max[i] = New_Max[i];//Copying from New_Max to Max because New_Max will be overwritten,so possible chaunce of dataloss
Not_Zero++;
}
while ((sizeof(Max) / 4 - (Not_Zero))>0)
{
Max[Not_Zero] = 0;
Not_Zero++;
}
/*Logic for calling recursive functions based on the count*/
if (count > 1)
{
count--;
Max_Min(1, 1, count, Max, Min);//Calling Recursive function by Passing Entire Arrays with flag 1.
}
else if (count == 1 && Max[1] == 0)
{
*n1 = Max[0];
*n2 = Min[0];
}
else if (count == 1 && Max[2] == 0)
{
Max_Min(1, 1, count + 1, Max, Min);
count--;
}
}
/*Logic for Finding Maximum & Minimum element is present down*/
if (flag == 0)
{
printf("flag");
if (Max_Min_flag == 1)
{
if (*n1 > *n2)
{
}
else if ((*n1 < *n2) && Max_Min_flag == 1)
{
int temp = 0;
temp = *n1;//5
*n1 = *n2;//7
*n2 = temp;//5
}
}
else if (Max_Min_flag == 2)
{
if (*n1 > *n2)//7>2
{
int temp = 0;
temp = *n1;//2
*n1 = *n2;//2
*n2 = temp;//2,7
}
else if (*n1 < *n2)
{
}
}
}
return *n1;//7
}
Problem is assigning Max[i]=New_Max[i] in function Max_Min().It shows Run time error as "Access violation writing location 0x00000000."
First you need to #include <stdlib.h> to use malloc
You must declare your function before using it.
func must return int*.
Also in func "n", first "Max", and second "Max" needs to be the same variable. Rename "n" to "Max"
This is the code corrected with an extra printf;
#include <stdio.h>
#include <stdlib.h>
int *Max,Number=5;
int* func(int *Max)
{
for(int j=0;j<5;j++)
Max[j]=j;//Its not working in this line
return Max;
}
int main()
{
Max=(int *) malloc(sizeof(int)*Number);
for(int i=0;i<5;i++)
Max[i]=i;
int* x = func(Max);
for(int i=0;i<5;i++)
printf("%d", x[i]);
}
The following contains only minor adaptations of your code and it runs fine:
int *func(int *n);
int *Max,Number=5;
int main()
{
int *x,i;
Max=(int *) malloc(sizeof(int)*Number);
for(i=0;i<Number;i++)
Max[i]=i;
x=func(Max);
free(Max);
return(0);
}
int *func(int *n)
{
int j;
for (j=0;j<Number;j++)
n[j]=Number-j; // reverse the number, just to check
return Max;
}
I'm writing a CUDA kernel and each thread has to complete the following task: suppose I have an ordered array a of n unsigned integers (the first one is always 0) stored in shared memory, each thread has to find the array index i such that a[i] ≤ threadIdx.x and a[i + 1] > threadIdx.x.
A naive solution could be:
for (i = 0; i < n - 1; i++)
if (a[i + 1] > threadIdx.x) break;
but I suppose this is not the optimal way to do it... can anyone suggest anything better?
Like Robert, I was thinking that a binary search has got to be faster that a naïve loop -- the upper bound of operation count for a binary search is O(log(n)), compared to O(N) for the loop.
My extremely simple implementation:
#include <iostream>
#include <climits>
#include <assert.h>
__device__ __host__
int midpoint(int a, int b)
{
return a + (b-a)/2;
}
__device__ __host__
int eval(int A[], int i, int val, int imin, int imax)
{
int low = (A[i] <= val);
int high = (A[i+1] > val);
if (low && high) {
return 0;
} else if (low) {
return -1;
} else {
return 1;
}
}
__device__ __host__
int binary_search(int A[], int val, int imin, int imax)
{
while (imax >= imin) {
int imid = midpoint(imin, imax);
int e = eval(A, imid, val, imin, imax);
if(e == 0) {
return imid;
} else if (e < 0) {
imin = imid;
} else {
imax = imid;
}
}
return -1;
}
__device__ __host__
int linear_search(int A[], int val, int imin, int imax)
{
int res = -1;
for(int i=imin; i<(imax-1); i++) {
if (A[i+1] > val) {
res = i;
break;
}
}
return res;
}
template<int version>
__global__
void search(int * source, int * result, int Nin, int Nout)
{
extern __shared__ int buff[];
int tid = threadIdx.x + blockIdx.x*blockDim.x;
int val = INT_MAX;
if (tid < Nin) val = source[threadIdx.x];
buff[threadIdx.x] = val;
__syncthreads();
int res;
switch(version) {
case 0:
res = binary_search(buff, threadIdx.x, 0, blockDim.x);
break;
case 1:
res = linear_search(buff, threadIdx.x, 0, blockDim.x);
break;
}
if (tid < Nout) result[tid] = res;
}
int main(void)
{
const int inputLength = 128000;
const int isize = inputLength * sizeof(int);
const int outputLength = 256;
const int osize = outputLength * sizeof(int);
int * hostInput = new int[inputLength];
int * hostOutput = new int[outputLength];
int * deviceInput;
int * deviceOutput;
for(int i=0; i<inputLength; i++) {
hostInput[i] = -200 + 5*i;
}
cudaMalloc((void**)&deviceInput, isize);
cudaMalloc((void**)&deviceOutput, osize);
cudaMemcpy(deviceInput, hostInput, isize, cudaMemcpyHostToDevice);
dim3 DimBlock(256, 1, 1);
dim3 DimGrid(1, 1, 1);
DimGrid.x = (outputLength / DimBlock.x) +
((outputLength % DimBlock.x > 0) ? 1 : 0);
size_t shmsz = DimBlock.x * sizeof(int);
for(int i=0; i<5; i++) {
search<1><<<DimGrid, DimBlock, shmsz>>>(deviceInput, deviceOutput,
inputLength, outputLength);
}
for(int i=0; i<5; i++) {
search<0><<<DimGrid, DimBlock, shmsz>>>(deviceInput, deviceOutput,
inputLength, outputLength);
}
cudaMemcpy(hostOutput, deviceOutput, osize, cudaMemcpyDeviceToHost);
for(int i=0; i<outputLength; i++) {
int idx = hostOutput[i];
int tidx = i % DimBlock.x;
assert( (hostInput[idx] <= tidx) && (tidx < hostInput[idx+1]) );
}
cudaDeviceReset();
return 0;
}
gave about a five times speed up compared to the loop:
>nvprof a.exe
======== NVPROF is profiling a.exe...
======== Command: a.exe
======== Profiling result:
Time(%) Time Calls Avg Min Max Name
60.11 157.85us 1 157.85us 157.85us 157.85us [CUDA memcpy HtoD]
32.58 85.55us 5 17.11us 16.63us 19.04us void search<int=1>(int*, int*, int, int)
6.52 17.13us 5 3.42us 3.35us 3.73us void search<int=0>(int*, int*, int, int)
0.79 2.08us 1 2.08us 2.08us 2.08us [CUDA memcpy DtoH]
I'm sure that someoneclever could do a lot better than that. But perhaps this gives you at least a few ideas.
can anyone suggest anything better?
A brute force approach would be to have each thread do a binary search (on threadIdx.x + 1).
// sets idx to the index of the first element in a that is
// equal to or larger than key
__device__ void bsearch_range(const int *a, const int key, const unsigned len_a, unsigned *idx){
unsigned lower = 0;
unsigned upper = len_a;
unsigned midpt;
while (lower < upper){
midpt = (lower + upper)>>1;
if (a[midpt] < key) lower = midpt +1;
else upper = midpt;
}
*idx = lower;
return;
}
__global__ void find_my_idx(const int *a, const unsigned len_a, int *my_idx){
unsigned idx = (blockDim.x * blockIdx.x) + threadIdx.x;
unsigned sp_a;
int val = idx+1;
bsearch_range(a, val, len_a, &sp_a);
my_idx[idx] = ((val-1) < a[sp_a]) ? sp_a:-1;
}
This is coded in browser, not tested. It's hacked from a piece of working code, however. If you have trouble making it work, I can revisit it. I don't recommend this approach on a device without caches (cc 1.x device).
This is actually searching on the full unique 1D thread index (blockDim.x * blockIdx.x + threadIdx.x + 1) You can change val to be anything you like.
You could also add an appropriate thread check, if the number of threads you intend to launch is greater than the length of your my_idx result vector.
I imagine there is a more clever approach that may use something akin to prefix sums.
This is the best algorithm so far. It's called: LPW Indexed Search
__global__ void find_position_lpw(int *a, int n)
{
int idx = threadIdx.x;
__shared__ int aux[ MAX_THREADS_PER_BLOCK /*1024*/ ];
aux[idx] = 0;
if (idx < n)
atomicAdd( &aux[a[idx]], 1); // atomics in case there are duplicates
__syncthreads();
int tmp;
for (int j = 1; j <= MAX_THREADS_PER_BLOCK / 2; j <<= 1)
{
if( idx >= j ) tmp = aux[idx - j];
__syncthreads();
if( idx >= j ) aux[idx] += tmp;
__syncthreads();
}
// result in "i"
int i = aux[idx] - 1;
// use "i" here...
// ...
}
void heapSort(int list[], int last)
{
// Local Declarations
int sorted;
int holdData;
int walker;
// Statements
for (walker = 1; walker <= last; walker++)
reheapUp (list, walker);
// Min Heap created. Now to sort!
sorted = last;
while (sorted > 0)
{
holdData = list[0];
list[0] = list[sorted];
list[sorted] = holdData;
sorted--;
reheapDown (list, 0, sorted, moves, comparisons);
}
return;
}
void reheapUp (int heap[], int newNode)
{
// Local Declarations
int parent;
int hold;
// Create a min heap
// Statements
if (newNode)
{
parent = (newNode - 1) / 2;
if (heap[newNode] > heap[parent]) // Only change made from ascending order
{
hold = heap[parent];
heap[parent] = heap[newNode];
heap[newNode] = hold;
reheapUp (heap, parent);
}
}
return;
}
void reheapDown (int heap[], int root, int last)
{
// Local Declarations
int hold;
int leftKey;
int rightKey;
int largeChildKey;
int largeChildIndex;
// Statements
if ((root * 2 + 1) <= last)
{
// There is atleast one child
leftKey = heap[root * 2 + 1];
if ((root * 2 + 2) <= last) {
rightKey = heap[root * 2 + 2];
}
else
rightKey = -1;
// Determine which child is larger
if (leftKey > rightKey)
{
largeChildKey = leftKey;
largeChildIndex = root * 2 + 1;
}
else
{
largeChildKey = rightKey;
largeChildIndex = root * 2 + 2;
}
// Test if root > large subtree
if (heap[root] < heap[largeChildIndex])
{
// parent < child
hold = heap[root];
heap[root] = heap[largeChildIndex];
heap[largeChildIndex] = hold;
reheapDown(heap, largeChildIndex, last);
}
}
return;
}
I got ascending order to heap sort to function by creating a max heap. I read that to create a descending order heap sort I need to create a min heap which I did as shown by changing heap[newNode] < heap[parent] to heap[newNode] > heap[parent] as shown in the code. However, it is still out order. Therefore, I wanted to do what are the other steps? Do I need to alter reheapDown somehow as well?
You need to change all value comparisons you make like heap[root] < heap[largeChildIndex] you didn't mention you changed.
First of all you need to change every comparison operators accordingly, just take them all and think of the problem.
Secondly you only have to reheapUp to (last/2) to create the heap, because the key at (last/2+1) doesn't have any childs.
And I made some heap-sort in C before and I had way less lines of code, and only had one "heapify" function. You might want to look at your code and try to simplify things.
EDIT : if you want some inspiration here is what I did
void fixHeap(int position,int length)
{
int child = (2*position)+1;
int temp;
while (child<=length)
{
if (child<length && vector[child]<vector[child+1])
{
child++;
}
if (vector[position]<vector[child])
{
temp = vector[position];
vector[position] = vector[child];
vector[child] = temp;
position = child;
child = (2*position)+1;
}
else
{
return;
}
}
}
void heapSort(int vector[],int N)
{
int counter;
int temp;
for (counter=(N-1)/2; counter>=0; counter--)
{
fixHeap(counter,N-1);
}
for (counter=N-1; counter>0; counter--)
{
temp = vector[counter];
vector[counter] = vector[0];
vector[0] = temp;
fixHeap(0,counter-1);
}
}
Here is heap sort using min heap implementation. Have a look, if it helps!
#include "stdafx.h"
#define LEFT(i) (2 * (i))
#define RIGHT(i) (((2 * (i)) + 1))
#define PARENT(i) ((i) / 2))
void print_heap(int input[], int n)
{
int i;
printf("Printing heap: \n");
for (i = 0; i < n; i++)
printf("%d ", input[i]);
printf("\n");
}
void swap_nodes(int *a, int *b)
{
int tmp;
tmp = *a;
*a = *b;
*b = tmp;
}
void min_heapify(int input[], int i, int n)
{
int least;
int l = LEFT(i + 1) - 1; // Get 0 based array index
int r = RIGHT(i + 1) - 1; // Get 0 based array index
if (l < n && input[l] < input[i]) {
least = l;
} else {
least = i;
}
if (r < n && input[r] < input[least]) {
least = r;
}
if (least != i) {
swap_nodes(&input[i], &input[least]);
min_heapify(input, least, n);
}
}
void heapify(int input[], int n)
{
for (int i = n/2; i >= 0; i--)
min_heapify(input, i, n);
}
void heap_sort(int input[], int n)
{
heapify(input, n);
for (int i = n - 1; i >= 1; i--) {
swap_nodes(&input[0], &input[i]);
n = n - 1;
min_heapify(input, 0, n);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
int input[] = {5, 3, 17, 10, 84, 19, 6, 22, 9, 1};
int n = sizeof(input) / sizeof(input[0]);
print_heap(input, n);
heap_sort(input, n);
print_heap(input, n);
return 0;
}