堆排序的几种方法及其时间复杂度
一.直接进行排序写法
先将数据进行排序,再依次存放在数组中即可
具体代码如下:
void Heapsort(int* a,int size) { assert(a); HP hp; Heapinit(&hp); for(int i=0;i<size;i++) { Heappush(&a,a[i]); } while(!Heapempty(&hp)) { a[i++]=HeapTop(&hp); Heappop(&hp); } }
但是此方法有着其不足之处即太麻烦,进行排序前还需要写插入与取头函数。
二.不利用堆函数的写法
首先需要建堆,有两种方法,自上而下与自下而上,分别利用两个函数即可。
向上调整函数具体代码如下:
void Adjustup(int* a,int child) { int parent; assert(a); parent=(child-1)/2; while(child>0) { if(a[child]>a[parent]) { Swap(&a[child],&a[parent]) child=parent; parent=(child-1)/2; } else { break; } } }
向下调整函数具体代码如下:
void AdjustDown(int* a, int n, int root) { int parent = root; int child = parent*2+1; while (child < n) { // 选左右孩纸中大的一个 if (child+1 < n && a[child+1] > a[child]) { ++child; } //如果孩子大于父亲,进行调整交换 if(a[child] > a[parent]) { Swap(&a[child], &a[parent]); parent = child; child = parent*2+1; } else { break; } } }
建堆第一种方法如下:(上调)
void Heapsort(int*a,int size) { assert(a); for(int i=1;i<size;i++) { AdjustUp(a,i); } }
建堆的第二种方式如下:(下调)
void Heapsort(int*a,int size,int child) { assert(a); for(int i=(size-2)/2;i>=0;i--) { AdjustDown(a,size,i); } }
但是向下调有一个前提条件就是左右子树必须是大堆或者小堆。
接下来我们就来计算一下时间复杂度:
第一种建堆的方法时间复杂度为o(N);
第二种建堆的方法时间复杂度为o(N*logN);
下一篇:
构建平衡二叉树(数据结构)