逐句解释堆排序
Posted Lotus_dong
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了逐句解释堆排序相关的知识,希望对你有一定的参考价值。
//堆排序1
private static int heapSize;//声明全局变量,记录堆中有多少元素
private static Integer[] array;//声明全局变量,存储传来要排序的元素
static void heapSort(Integer[] arr) {
array = arr;
//原地建堆
heapSize = arr.length;
//从最后一个非叶子节点向上构建最大堆(二叉堆的逻辑结构是一个完全二叉树,最后一个非叶子节点索引=节点数/2-1)
for (int i = (heapSize >> 1) - 1; i >= 0; i--) {
siftDown(i);
}
//交换---堆顶元素和堆尾元素,直到堆中元素只剩1个
while (heapSize > 1) {
Integer tmp = arr[0];//堆顶元素
heapSize--;
arr[0] = arr[heapSize];
arr[heapSize] = tmp;
//对堆顶元素0位置进行下滤操作,恢复堆的性质
siftDown(0);
}
}
//下滤---自底向上原地建堆
private static void siftDown(int index) {//传入要下滤的节点
Integer element = array[index];//获取传入的节点的元素
int half = heapSize >> 1;//将元素个数减半,判断,传入节点是否是叶子结点
//以完全二叉树作为逻辑结构, 节点数量减半后的索引位置都是叶子节点
while (index < half) {//index位置必须非叶子节点
//获取左孩子节点,不是叶子节点,左节点一定不为空
int childrenIndex = (index << 1) + 1;
int child = array[childrenIndex];//获取左孩子元素
int rightIndex = childrenIndex + 1;//右孩子索引就是左孩子+1
//判断右孩子索引在数组容量范围内, 右孩子节点大于左孩子节点
if (rightIndex < heapSize && array[rightIndex]- child > 0) {
//将childrenIndex指向值更大的孩子
childrenIndex = rightIndex;
//将child变为更大的值
child = array[rightIndex];
}
//判断传入元素大于>=孩子节点
if (element - child >= 0) {
break;//跳出
}
//到这里代表传入元素比孩子节点元素小
array[index] = child;//就将对应的孩子换到父节点的索引位置
index = childrenIndex;//再将索引换成原本的孩子节点
}
array[index] = element;//索引元素最后在堆中的位置
}
以上是关于逐句解释堆排序的主要内容,如果未能解决你的问题,请参考以下文章
scratch图解排序算法:插入排序冒泡排序选择排序归并排序快速排序堆排序