1、算法描述
利用堆(大根堆或小根堆)这种数据结构所设计的一种算法。
堆:堆是一个特定的完全二叉树,树中的任一节点的值都不大于(或不小于)其左右孩子(如果存在)节点的值。
操作步骤(以大根堆为例)
初始序列无需区R(1,n),有序区为空
(1)、对无序区建大根堆。
(2)、交换大根堆的堆顶和堆的最后一个元素,得到新的无序区以及有序区
(3)、重复(1)(2)直至无序区的元素个数为1
(4)、对整棵树做顺序访问
2、图例
3、代码
public void sort(int[] data) {
MaxHeap mh = new MaxHeap(data);
mh.remove(data);
}
class MaxHeap {
public MaxHeap() {
}
// 构建堆
public MaxHeap(int[] data) {
if (data.length <= 1)
return;
int i = data.length - 1;
while (i > 0) {
int j = i >> 1;
if (data[i] > data[j]) {
swap(data, i, j);
}
i--;
this.size++;
}
this.size++;
}
// 调整堆
private void formatHeap(int[] data) {
if (this.size <= 1)
return;
int j = 0;
int k = (j + 1) << 1;
while (k <= this.size) {
if (k < this.size) {
if (data[k - 1] > data[k]) {
k--;
}
} else {
k--;
}
if (data[k] <= data[j]) {
break;
}
swap(data, k, j);
j = k;
k = (j + 1) << 1;
}
}
public void remove(int[] data) {
while (this.size > 1) {
swap(data, 0, --this.size);
if (this.size == 1)
break;
formatHeap(data);
}
}
int size;
}
4、稳定性和复杂度
稳定性:堆排序是不稳定的排序
平均时间复杂度:O(nlongn)
堆排序的时间复杂度主要由构建堆和调整堆决定。构建堆是O(n),每一次调整堆的时间复杂度为O(longn),调整了n-1次。
空间复杂度:O(1)