行者

慢慢走,不要停
  博客园  :: 新随笔  :: 管理

堆排序

Posted on 2020-06-01 18:35  angury  阅读(0)  评论(0编辑  收藏  举报
#include<stdio.h>
void swap(int A[],int i,int j)
{

    int tmp=A[i];
    A[i]=A[j];
    A[j]=tmp;
}
void heapify(int A[],int N,int i)
{
/*可有可无
if(i>=N) { return; }
*/
int c1=2*i+1; int c2=2*i+2; int max=i; if(c1<N&&A[c1]>A[max]) { max=c1; } if(c2<N&&A[c2]>A[max]) { max=c2; } if(max!=i)/*错误写为while···*/ { swap(A,i,max); heapify(A,N,max); /* 对一个节点做heapify的时候,必须保证它的所有子树都已经是堆。 所以,在这个前提下,如果要做heapify的节点已经符合“父节点 > 子节点”的性质,那么这就已经是一个堆了;就没有必要往下走了。 另外,我们的build_heap函数是从最后一个不是叶节点的点开始往前做heapify操作的,所以最后是可以形成一个堆。 如果max不等于i说明需要将节点i和子节点max交换,交换后,递归调用heapify max节点保证以max为根的子树也构成堆结构。 因为heapify是在build_heap里调用的,而build_heap是从最后一个父节点往树上面调用,
在中间某层如果i和max换了,可能会破max为根的坏子树的堆结构,才需要递归保证以max为根的子树为堆,否则并不需要,因为是从下往上建堆,子树一定是堆结构。
*/ } } void build_heap(int A[],int N) { int last_node=N-1; int parent=(last_node-1)/2; int i; for(i=parent;i>=0;i--) { heapify(A,N,i); /*粗心错误:将i写成parent*/ } } void heap_sort(int A[],int N) { build_heap(A,N); int i; for(i=N-1;i>=0;i--) { swap(A,i,0);/*粗心错误:swap(A,A[i],0)*/ heapify(A,i,0);/*heapify即可,不必新建堆*//*(A,N,0)错误,i之后的已经排好序了*/ } } int main() { int A[10]={1,6,7,5,2,3,4,9,0,63}; int N=10; heap_sort(A,N); int i; for(i=0;i<N;i++) { printf("%d ",A[i]); } return 0; }