堆排序
2017-08-27 16:50
92 查看
大根堆定义为,每一个父亲节点都大于等于左右两个孩子节点(小根堆同理)。并且,大根堆一定是一棵完全二叉树。思想为从最后一个家庭开始(最后一个有孩子的父亲节点),将这个家庭调整为大根堆,然后父亲节点前移,将下一个家庭调整为大根堆……以此类推,最后,根节点就是最大的元素,然后将根节点与最后一个叶子节点交换,砍掉最后一个叶子节点(意思就是下一轮的排序它不参与)。
时间复杂度:o(nlogn) 不稳定
#include <stdio.h> void HeapSort(int a[],int n) { int rear,t,pa,tag=0;//tag:标志变量 用处:检查大根堆是否完成 rear=n; while(rear>1) { while(1)//与检查tag变量是否有变化一起合作,调整成大根堆 { pa=rear/2;//最后一个父亲节点,rear奇偶情况都适用 tag=0; while(pa>0) { if(a[pa]<a[pa*2])//左子女不用检查 直接比较 { t=a[pa]; a[pa]=a[pa*2]; a[pa*2]=t; tag=1; } if(2*pa+1<=rear&&a[pa]<a[pa*2+1])//右子女检查是否存在 再比较 { t=a[pa]; a[pa]=a[pa*2+1]; a[pa*2+1]=t; tag=1; } pa--; } if(!tag)//是否调整成大根堆的判断 break; } t=a[1];//交换"头"与"尾" "砍掉"! a[1]=a[rear]; a[rear]=t; rear--; } } int main(void) { int a[11]={0,1,3,6,8,4,2,5,9,7,10}; int i; HeapSort(a,10); for(i=10;i>0;i--) printf("%d\t",a[i]); return 0; }
时间复杂度:o(nlogn) 不稳定