复杂度最坏: nlgn 代码中有标注
和top n 问题关系:用的堆模型,和top n 问题用的模型相同
http://blog.csdn.net/nx188/article/details/51218846
createHeap 从1开始遍历堆去令每个节点做child, 用child 去找parent,
adjustHeap parent 一直是0, 用parent 去和lChild 和rChild 去比较, 这个是log N, 每个节点都置换一次最小值, 就是O(n), 所以是nlogN
代码:
package AlgorithmTopK;
public class Heapsort {
//建立小根堆 super.createHeap(int input[], int K);
public int[] createHeap(int input[]) { //创建小根堆
int heap[] = new int[input.length];
for(int i=0;i<input.length;i++)
heap[i] = input[i];
for(int i = 1;i < heap.length;i++) { //这个复杂度是 n
int child = i;
int parent = (child-1) / 2;
while(parent >= 0 && child!=0 && heap[parent] > heap[child]) { //这个复杂度最坏是lgn
int temp = heap[child];
heap[child] = heap[parent];
heap[parent] = temp;
child = parent;
parent = (parent - 1) / 2;
}
}
return heap;
}
//循环根和最后一个换,再调整堆 根和倒数第二个换,再调整堆 直到根和左儿子交换后,不用再调整堆
public void adjustHeap(int[] heap, int last) {
//先把根和heap[last]交换,
int temp = heap[0];
heap[0] = heap[last];
heap[last] = temp;
//再调整堆
if(last > 1) {
int parent = 0;
while(parent < last-1) { //这个循环复杂度最坏是 lgn
int lchild = parent*2 + 1;
int rchild = parent*2 + 2;
int minIndex = parent; //指向左右儿子中最小的
if(lchild < last-1 && heap[lchild] < heap[parent])
minIndex = lchild;
if(rchild < last-1 && heap[rchild] < heap[minIndex])
minIndex = rchild;
if(minIndex == parent) {
break;
}
else {
temp = heap[minIndex];
heap[minIndex] = heap[parent];
heap[parent] = temp;
parent = minIndex;
}
}
}
}
//打印结果数组
public int[] heapSort(int[] input) {
int[] smallRootHeap = createHeap(input); //复杂度最坏是nlgn
for(int i=smallRootHeap.length-1;i>0;i--) //复杂度最坏是nlgn
adjustHeap(smallRootHeap, i);
return smallRootHeap;
}
public static void main(String[] args) {
int a[] = {5,4,1,2,6,7,9,10,2,3};
int result[] = new Heapsort().heapSort(a);
for(int resultItem : result) {
System.out.print(resultItem + " ");
}
}
}
结果:
10 9 7 6 5 4 3 2 2 1