堆排序
2017-07-08 16:03
375 查看
排序算法--堆排序(大根堆实现)
堆排序的平均时间复杂度 :O(N*logN)空间复杂度:O(1)
堆排序算法的演示。首先,将元素进行重排,以匹配堆的条件。图中排序过程之前简单的绘出了堆树的结构。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define LEFT 2*nRootID+1
#define RIGHT 2*nRootID+2
//1.建初始堆
// (1)从最后一个父亲节点开始
// 1.1比较左右孩子大小
// 1.2拿大的和父亲比较
// 比父亲大:与父亲交换,被交换位置作为新的被调整节点,重复1.1和1.2
// 比父亲小:结束,进行下一个父亲节点 的调整
//2.排序
// 2.1 拿堆顶与当前数组的最后位置值交换
// 2.2最后位置元素不参与运算
//
//调整父亲节点 void Adjust(int a[],int nlen,int nRootID) { while (1) { //两个孩子 if(RIGHT<nlen) { //比较两个孩子大小,大的和父亲交换值 if(a[LEFT]>a[RIGHT]) { if(a[LEFT]>a[nRootID]) { //和父亲节点值交换 a[LEFT]^=a[nRootID]; a[nRootID]^=a[LEFT]; a[LEFT]^=a[nRootID]; nRootID=LEFT; continue; } else { break; } } else { if(a[RIGHT]>a[nRootID]){ a[RIGHT]^=a[nRootID]; a[nRootID]^=a[RIGHT]; a[RIGHT]^=a[nRootID]; nRootID=RIGHT; continue; } else { break; } } } //一个孩子 else if (LEFT<nlen) { if(a[LEFT]>a[nRootID]) { //大的和父亲交换 a[LEFT]^=a[nRootID]; a[nRootID]^=a[LEFT]; a[LEFT]^=a[nRootID]; nRootID=LEFT; continue; } else { break; } } else { //没有孩子 break; } } } void Adjust2(int a[],int nlen,int nRootID) { int MAX; for(MAX=LEFT;MAX<nlen;MAX=LEFT) { //2个孩子 if(RIGHT<nlen) { if(a[RIGHT]>a[LEFT]) { MAX=RIGHT; } } //大的和父亲节点交换 if(a[MAX]>a[nRootID]) { a[MAX]^=a[nRootID]; a[nRootID]^=a[MAX]; a[MAX]^=a[nRootID]; nRootID=MAX; } else { break; } } }
void HeapSort(int a[],int nlen) { int i; if(a==NULL ||nlen<=0) return ; //从最后一个父亲节点开始调整 for(i=nlen/2-1;i>=0;i--) {
//Adjust(a,nlen,i); Adjust2(a,nlen,i); } //排序 for(i=nlen-1;i>0;i--) {
//从最后一个父亲节点开始调整为大根堆a[0]^=a[i];a[i]^=a[0];a[0]^=a[i];//重新调整堆顶
//Adjust2(a,i,0); Adjust2(a,i,0); } } int main() { int i; int a[]={5,3,2,1,4,6,8,9,7}; int len=sizeof(a)/sizeof(a[0]); HeapSort(a,len); for(i=0;i<len;i++) { printf("%d ",a[i]); } system("pause"); return 0; }