//堆排序
//堆排序其实就是构建一个大顶堆或小顶堆,这和堆的实现差不多
public class HeapSort {
// 升序排列就构建一个大顶堆,每次取堆顶元素放到末尾。
// 降序排列就构建一个小顶堆,每次取堆顶元素放到末尾。
public void maxHeapSort(int[] data, int left, int right) {
if (left < 0 || right > data.length - 1 || left >= right) {
return;
}
int index, high;
high = right;//记录已排好的区域
// 构建一个大顶堆,找到第一个非叶子节点,然后对所有非叶子节点进行一次下沉。
while (left <= parent(high, left)) {
for (int i = parent(high, left); i >= left; i--) {
// 进行下沉操作
index = i;
// 确保子节点没有超出范围
while (leftChild(index, left) <= high) {
int child = leftChild(index, left);
// 选出最大的子节点去和父节点比较
// 小顶堆只需把第二个条件的判断改为'<'即可
if (rightChild(index, left) <= high &&
data[rightChild(index, left)] >
data[leftChild(index, left)]) {
child++;
}
// 小顶堆只需把'>'改为'<'即可
if (data[child] > data[index]) {
int temp = data[child];
data[child] = data[index];
data[index] = temp;
index = child;
} else {
break;
}
}
}
int temp = data[left];
data[left] = data[high];
data[high] = temp;
high--;
}
}
// 原来的堆的子节点与父节点关系:leftChild = parent*2 + 1,rightChild = parent*2 +
// 2 ;
// 原来的利用int的特性,求父节点时:parent = (child-1)/2;
// 因为这里起点是left,不一定是0,所有子节点全部+left。求父节点也修改一下,由子节点公式推导出来。
private int parent(int index, int left) {
return (index + left - 1) / 2;
}
private int leftChild(int index, int left) {
return index * 2 + 1 - left;
}
private int rightChild(int index, int left) {
return index * 2 + 2 - left;
}
}
八大排序算法——堆排序(四)
最新推荐文章于 2024-07-17 09:11:28 发布