一、代码
/* 堆:堆是一棵完全二叉树; //堆是完全二叉树,完全二叉树不一定是堆; 分类:大根堆 根比左右子树大; 小根堆 根比左右子树小; 堆排序:(升序为例) 1.数据集合的存储:将数据集合存储为完全二叉树; 2.将end指向最后一个结点,pa指向最后一个双亲结点, 双亲分别于左右子树交换,比左子树大不变,反之交换,之后比较右子树, 最后pa--; 3.直到比较到root,root此时为最大,将此时的root与end交换,砍掉end, 将end--指向最后一个结点,直到end指向root根结点; */ #include<stdio.h> #define N 11 void HeapSort(int a[]) { int end=N-1; //end指向最后一个元素; while(end!=0) //end到根结点结束 { while(1) { int pa=end/2-1; //指向最后一个双亲结点; //printf("%d %d %d\n",a[pa],a[2*pa],a[2*pa+1]); int tag=0; //判断是否还需要进行第二步; //将最大值移至下标为1的位置; while(pa>=0) //进行一次pa从最后一个双亲结点到第一个; { if(a[pa]<a[2*pa+1]) //双亲与其左孩子比较; { tag=1; int temp=a[pa]; a[pa]=a[2*pa+1]; a[2*pa+1]=temp; } //2*pa+1<=end,防止越界; if((2*pa+1<=end) && a[pa]<a[2*pa+2]) //双亲与其右孩子比较; { tag=1; int temp=a[pa]; a[pa]=a[2*pa+2]; a[2*pa+2]=temp; } pa--; //进行--操作,移向上一个双亲; } if(tag==0) //说明这次循环没有进行交换,说明已经找到的最大值; { //将最大值放在数组的最后一位,之后的次大值一次放这个位置的前一个位置; int t=a[0]; a[0]=a[end]; a[end]=t;//将这次找到的最大值放置在a[end]; break; } } end--; //end前移,用来放置下一个循环的最大值; } printf("堆排序后的数组为:\n"); for(int i=0;i<N;i++) printf("%d ",a[i]); printf("\n"); } int main(void) { int a[N]={10,3,2,5,8,4,7,6,9,1,11}; printf("原始数据为:\n"); for(int i=0;i<N;i++) printf("%d ",a[i]); printf("\n\n"); HeapSort(a); return 0; }