C实现heap堆排序
所谓的堆排序,就是把数组虚拟成二叉堆。其定义必须满足如下2个条件中的一个条件: 假设数组a[n] (1) 二叉堆中的父节点a[r] 必须大于等于子节点 (2)二叉堆的父节点必须小于等于子节点 Parent(i): return a[(i] Left(i): return a[(i+1)<<1-1] Right(i): return a[(i+1)<<1] 二叉堆的维护(移动对应节点的值): a的数组大小为 asize 二叉堆当前的有效元素的大小为psize adjustheap(a,i): left = (i+1)<<1-1; right = (i+1)<<1; big = i if left< psize && a[left] >= a[i] big =left if right < psize && a[right] >= a[i] big = right if big != i swap(a[big],a[i] adjustheap(a,big) 建堆: build(a): psize = asize for i= psize>>2-1 downto 1 adjustheap(a,i) 排序: sort(a): bulid(a) psize = size -1 for i = psize and i>0 and i--: swap(a[i],a[0]) psize--; adjustheap(a[i],0)
/************************************************************************* > File Name: heapsort.c > Author: zhoulin > Mail: 715169549@qq.com > Created Time: Wed 30 Mar 2016 03:39:20 AM CST ************************************************************************/ #include "heapsort.h" #include <stdio.h> static void Swap(int *a,int *b) { *a = *a^*b; *b = *a^*b; *a = *a^*b; } void AdjustHeapBig(heap *hp,int i) { unsigned int left = (i+1)<<1-1; // array is start with 0 unsigned int right = (i+1)<<1; unsigned int big = i; int *arr = hp->arr; unsigned int max = hp->index; if(left <= max && arr[left] <= arr[i]) { big = left; } if(right <= max && arr[right] <= arr[big]) { big = right; } if(big != i) { Swap(&arr[big],&arr[i]); AdjustHeapBig(hp,big); } } void AdjustHeapSmall(heap *hp,int i) { unsigned int left = (i+1)<<1-1; // array is start with 0 unsigned int right = (i+1)<<1; unsigned int small = i; int *arr = hp->arr; unsigned int max = hp->index; if(left <= max && arr[left] >= arr[i]) { small = left; } if(right <= max && arr[right] >= arr[small]) { small = right; } if(small != i) { Swap(&arr[small],&arr[i]); AdjustHeapSmall(hp,small); } } void SortHeapBig(heap *hp) { int *arr = hp->arr; int size = hp->len; int i; for(i = size>>1-1;i >= 0; i--) { AdjustHeapBig(hp,i); } while(hp->index > 0) { Swap(&arr[0],&arr[hp->index]); hp->index--; AdjustHeapBig(hp,0); } } void SortHeapSmall(heap *hp) { int *arr = hp->arr; int size = hp->len; int i; for(i = size>>1-1;i >= 0; i--) { AdjustHeapSmall(hp,i); } while(hp->index > 0) { Swap(&arr[0],&arr[hp->index]); hp->index--; AdjustHeapSmall(hp,0); } } int main(void) { int i; int arr[11] = {19,2,45,80,21,56,1,100,3,99,19}; fprintf(stdout,"****************src array******************\n\n"); for(i = 0; i< 11;i++) { if(i == 10) { fprintf(stdout," %d\n",arr[i]); break; } fprintf(stdout," %d ,",arr[i]); } heap p; p.len = 11; p.arr = arr; p.index = p.len -1; SortHeapBig(&p); fprintf(stdout,"****************big heap sort******************\n\n"); for(i = 0; i< p.len;i++) { if(i == p.len -1) { fprintf(stdout," %d\n\n",arr[i]); break; } fprintf(stdout," %d ,",arr[i]); } // insert sort int arr2[11] = {19,2,45,80,21,56,1,100,3,99,19}; for(i = 0;i < 11;i++) { p.len = i+1; p.arr = arr2; p.index = p.len-1; SortHeapBig(&p); int j = 0; fprintf(stdout,"---------sort %d-------------------\n",i+1); for(;j<=i;j++) { if(j == i) { fprintf(stdout," %d\n\n",arr2[j]); break; } fprintf(stdout," %d ,",arr2[j]); } } // int arr1[11] = {19,2,45,80,21,56,1,100,3,99,19}; p.len = 11; p.arr = arr1; p.index = p.len -1; SortHeapSmall(&p); fprintf(stdout,"****************small heap sort******************\n\n"); for(i = 0; i< p.len;i++) { if(i == p.len-1) { fprintf(stdout," %d\n\n",arr1[i]); break; } fprintf(stdout," %d ,",arr1[i]); } return 0; }
运行结果:
****************src array****************** 19 , 2 , 45 , 80 , 21 , 56 , 1 , 100 , 3 , 99 , 19 ****************big heap sort****************** 100 , 99 , 80 , 56 , 45 , 21 , 19 , 19 , 3 , 2 , 1 ---------sort 1------------------- 19 ---------sort 2------------------- 19 , 2 ---------sort 3------------------- 45 , 19 , 2 ---------sort 4------------------- 80 , 45 , 19 , 2 ---------sort 5------------------- 80 , 45 , 21 , 19 , 2 ---------sort 6------------------- 80 , 56 , 45 , 21 , 19 , 2 ---------sort 7------------------- 80 , 56 , 45 , 21 , 19 , 2 , 1 ---------sort 8------------------- 100 , 80 , 56 , 45 , 21 , 19 , 2 , 1 ---------sort 9------------------- 100 , 80 , 56 , 45 , 21 , 19 , 3 , 2 , 1 ---------sort 10------------------- 100 , 99 , 80 , 56 , 45 , 21 , 19 , 3 , 2 , 1 ---------sort 11------------------- 100 , 99 , 80 , 56 , 45 , 21 , 19 , 19 , 3 , 2 , 1 ****************small heap sort****************** 1 , 2 , 3 , 19 , 19 , 21 , 45 , 56 , 80 , 99 , 100