堆排序
基于二叉堆的特性:
最大堆的堆顶是整个堆中的最大元素
最小堆的堆顶是整个堆中的最小元素
以最大堆为例,如果删除最大堆的堆顶(并不是完全删除,而是跟末尾节点交换位置),经过自我调整之后,第二大的元素会被交换成最大堆的新堆顶
不停的删除堆顶,反复调整,最后最大堆就会变成一个从小到大的有序集合
而且二叉堆实际是存储在数组中,则该数组就是一个从小到大有序的数组
代码实现
//下沉 调整
public static void downAdjust(int[] arr, int parentIndex, int length)
{
//tmp保存父节点,用于最后赋值
int tmp = arr[parentIndex];
int childIndex = 2 * parentIndex + 1;
while(childIndex < length)
{
//如果有右孩子且右孩子大于左孩子,则定位到右孩子
if(childIndex + 1 < length && arr[childIndex + 1] > arr[childIndex])
{
childIndex ++;
}
//如果父节点大于任何一个孩子的值,则结束
if(tmp >= arr[childIndex])
break;
arr[parentIndex] = arr[childIndex];
parentIndex = childIndex;
childIndex = 2 * childIndex + 1;
}
arr[parentIndex] = tmp;
}
//堆排序(升序)
public static void heapSort(int[] arr)
{
//把无序数组构建成最大堆
for(int i = (arr.length -2)/2;i >= 0;i --)
{
downAdjust(arr, i, arr.length);
}
//循环删除堆顶元素,
for(int i = arr.length - 1;i > 0;i --)
{
//最后一个元素与堆顶元素进行交换
int tmp = arr[i];
arr[i] = arr[0];
arr[0] = tmp;
downAdjust(arr, 0, i);
}
}