1,堆排序算法是树形选择排序的改进,使其空间复杂度降低到O(1),时间复杂度O(nlogn)。
思想:通过将输入序列构建成大顶堆。并在插入,删除,修改的过程中重新向上或向下调整成大顶堆。使最大的数据在堆顶。所以在输出过程中每次取出堆顶元素输出就得到输入序列的降序排列。重点是向上和向下调整成大顶堆的算法。
2,Java代码基本实现:
/**
* 树形选择排序的改进:堆排序。
*
*/
public class HeapSort {
public static class Heap {
int[] heapArray;
int maxSize;
int currentSize;
public Heap(int maxSize) {
heapArray = new int[maxSize];
this.maxSize = maxSize;
}
public void insert(int value) {
if (currentSize == maxSize) {
return;
}
heapArray[currentSize] = value;
trickleUp(currentSize);//调整成
currentSize++;
}
/**
* 增加节点时向上重建大顶堆。
*
* @param index
*/
private void trickleUp(int index) {
int parent = (index - 1) / 2;
int newValue = heapArray[index];
//从数组末尾向前寻找或称为从二叉树的向上调整。
while (index > 0 && newValue > heapArray[parent]) {
heapArray[index] = heapArray[parent];
index = parent;
parent = (index - 1) / 2;
}
heapArray[index] = newValue;
}
/**
* 删除节点时向下重建大顶堆。
*
* @param index
*/
private void trickledDown(int index) {
int lastValue = heapArray[index];
int largeChild;
while (index < currentSize / 2) {
int leftChild = 2 * index + 1;
int rightChld = leftChild + 1;
if (rightChld < currentSize && heapArray[leftChild] < heapArray[rightChld]) {
largeChild = rightChld;
} else {
largeChild = leftChild;
}
if (lastValue >= heapArray[largeChild]) {
break;
}
heapArray[index] = heapArray[largeChild];
index = largeChild;
}
heapArray[index] = lastValue;
}
public int remove(int index) {
int deletedValue = heapArray[index];
heapArray[index] = heapArray[--currentSize];
trickledDown(index);
return deletedValue;
}
/**
* 输出排序好的数据。
*/
public void displaySorted() {
int[] tmp = new int[currentSize];
for (int i = tmp.length - 1; i >= 0; i--) {
tmp[i] = remove(0);//大顶堆本身是降序输出的。
}
LogUtils.e(tmp);
}
}
public static void test() {
Heap heap = new Heap(100);
heap.insert(1);
heap.insert(6);
heap.insert(5);
heap.insert(9);
heap.insert(91);
heap.insert(19);
heap.displaySorted();
}
}