堆排序算法,属于比较排序的一种。
时间复杂度 O(nlogn)
,
空间复杂度O(1)
. 从这一点就可以看出,堆排序在时间上类似归并,但是它又是一种原地排序,时间复杂度小于归并的O(n+logn)
排序时间与输入无关,最好,最差,平均都是O(nlogn)
. 不稳定
堆排序借助了堆这个数据结构,堆类似二叉树,又具有堆积的性质(子节点的关键值总小于(大于)父节点) 堆排序包括两个主要操作:
- 保持堆的性质heapify(A,i)时间复杂度
O(logn)
- 建堆 buildmaxheap(A)时间复杂度
O(n)
线性时间建堆
对于大数据的处理: 如果对100亿条数据选择Topk数据,选择快速排序好还是堆排序好? 答案是只能用堆排序。 堆排序只需要维护一个k大小的空间,即在内存开辟k大小的空间。而快速排序需要开辟能存储100亿条数据的空间。
代码:
void buildHeap(int array[]){
int length = array.length;
int heapsize = length;
int nonleaf = length / 2 - 1;
for(int i = nonleaf; i>=0;i--){
heapify(array,i,heapsize);
}
}
void heapify(int array[], int i,int heapsize){
int smallest = i;
int left = 2*i+1;
int right = 2*i+2;
if(left<heapsize){
if(array[i]>array[left]){
smallest = left;
}
else smallest = i;
}
if(right<heapsize){
if(array[smallest]>array[right]){
smallest = right;
}
}
if(smallest != i){
int temp;
temp = array[i];
array[i] = array[smallest];
array[smallest] = temp;
heapify(array,smallest,heapsize);
}
}
void heapsort(int array[]){
int heapsize = array.length;
buildHeap(array);
for(int i=0;i<array.length-1;i++){
int temp;
temp = array[0];
array[0] = array[heapsize-1];
array[heapsize-1] = temp;
heapsize = heapsize - 1;
heapify(array,0,heapsize);
}
}