递归排序之堆排序
堆排序的基础构建堆的数据结构是一颗完全二叉树,完全二叉树大概就是所有的数据都是从上到下,从左到右依次插入数据。
堆的特性,大顶堆:父节点大于子节点;小顶堆:父节点小于子节点。
下面给出代码方便分析
1 #include<stdio.h> 2 3 //这个程序需要注意heapify和buildheap的区别 4 //heapify只保证改变的最大值那一个子树满足堆的性质, 5 //因为只递归改变索引的那一个子树,另外一个子树则不会取判断 6 //又可能那个子树就不满足堆的性质 7 /* 8 4 9 / \ 10 10 3 11 / \ / \ 12 5 1 2 8 13 / \ 14 7 6 15 当对上述的二叉树的0索引进行heapify后,看下图,左子树满足堆性质,但右子树不满足 16 只有buildheap这个函数才能满足建堆性质 17 10 18 / \ 19 5 3 20 / \ / \ 21 7 1 2 8 22 / \ 23 4 6 24 而heapsort时,heapsort和heapify都可以,因为另外一个子树也满足堆性质,不需再调整 25 */ 26 27 28 void swap(int arr[],int i,int j) 29 { 30 int temp=arr[i]; 31 arr[i]=arr[j]; 32 arr[j]=temp; 33 } 34 35 //对于一个堆来说,若假定当前节点为i,则 36 //父节点索引为 (i-1)/2,左右子节点分别为 c1=2*i+1; c2=2*i+1; 37 void heapify(int arr[],int n,int i) 38 { 39 if(i>=n) 40 { 41 return ; 42 } 43 int c1=2*i+1; 44 int c2=2*i+2; 45 int max=i; 46 if(c1<n && arr[c1]>arr[i]) 47 { 48 max=c1; 49 } 50 if(c2<n&& arr[c2]>arr[max]) 51 { 52 max=c2; 53 } 54 if(max!=i) 55 { 56 swap(arr,max,i); 57 heapify(arr,n,max); 58 } 59 } 60 61 void buildheap(int arr[],int n) 62 { 63 int last_node=n-1; 64 int parent=(last_node-1)/2; 65 int i; 66 for(i=parent;i>=0;i--) 67 { 68 heapify(arr,n,i); //这里的heapify 需要递归,要不可能上层的变动导致子树的堆性质改变 69 } 70 } 71 void heapsort(int arr[],int n) 72 { 73 int i; 74 for(i=n-1;i>=0;i--) 75 { 76 swap(arr,0,i); 77 //heapify(arr,i,0); 78 buildheap(arr,i); //这两个都可以,因为此时使用heapify,另外一个子树也满足堆性质 79 } 80 } 81 void Print(int A[],int N) 82 { 83 int i; 84 for(i=0;i<N;i++) 85 { 86 printf(" %d ",A[i]); 87 } 88 } 89 int main() 90 { 91 //const int n=6; 92 int arr[9]={4,10,3,5,1,2,8,7,6}; 93 Print(arr,9); 94 printf("\n"); 95 buildheap(arr,9); 96 heapsort(arr,9); 97 Print(arr,9); 98 printf("\n"); 99 return 0; 100 }