赞
踩
堆是具有以下性质的完全二叉树:
- 每个节点都大于或等于其做孩子节点的值,成为大顶堆。
- 每个节点的值都小于或等于左右孩子节点的值,称为小顶堆。
举例来说,对于n个元素的序列{R0, R1, … , Rn}当且仅当满足下列关系之一时,称之为堆:
(1) Ri <= R2i+1 Ri <= R2i+2 (小根堆)
(2) Ri >= R2i+1 且 Ri >= R2i+2 (大根堆)
1)首先,将数组R[0…n]调整为大顶堆或小顶堆(大顶堆排序后是从小到大,小顶堆排序后是从大到小,本文以大顶堆例)
2)调整结束后R0就是数组中最大的一个值,然后将R[0]和R[n]交换,输出R[n]。
3)因为最大值已经出来,我们需要将其排除再外,放到数组最后,然后继续找最大值。即将R[0…n-1]重新调整为堆,交换R[0]和R[n-1];
4)如此反复,直到交换了R[0]与R[1]为止。 此时的数组R[0…n]已经是顺序排序。
其实主要操作就两个:
当输出完最后一个元素后,这个数组已经是按照从小到大的顺序排列了。
步骤一 、构造初始堆。将给数组构造成一个大顶堆
****
步骤二 将堆顶元素与末尾元素进行交换,使末尾元素最大。然后继续调整堆,再将堆顶元素与末尾元素交换,得到第二大元素。如此反复进行交换、重建、交换。即可得到最终排序后的序列
将堆顶元素9和末尾元素4进行交换
重新调整结构,使其继续满足堆定义
后续过程,继续进行调整,交换,如此反复进行,最终使得整个序列有序
package tree; import java.util.Arrays; /** * @author lixiangxiang * @description / * @date 2021/6/22 10:58 */ public class HeapSort { public static void main(String[] args) { int arr[] = {4, 6, 8, 5, 9}; heapSort(arr); System.out.println(Arrays.toString(arr)); } private static void heapSort(int[] arr) { //将数组构建成大顶堆 for(int i = arr.length / 2 -1; i >=0; i--) { adjustHeap(arr, i, arr.length); } //将堆顶元素和末尾元素叫魂 //重新调整结构,使其满足堆定义 int temp = 0; for(int j = arr.length-1;j >0; j--) { //交换 temp = arr[j]; arr[j] = arr[0]; arr[0] = temp; adjustHeap(arr, 0, j); } } /** * description: 调整大顶堆的过程, * * @author: lixiangxiang * @param arr 数组 * @param i 非叶子节点下标 * @param length 数组的长度 * @return void * @date 2021/7/11 11:40 */ private static void adjustHeap(int[] arr,int i,int length) { //取出当前元素 int temp= arr[i]; //获取当前元素的左子节点下表 int child = 2 * i + 1; while(child < length ) { //如果右子节点的值大于左子节点,让child = 右子节点的下标 即获取孩子中值最大的一个的下标 if (child + 1 < length && arr[child] < arr[child + 1]) { child ++; } //如果父节点的值已经大于等于子节点的值,则直接跳过 if (arr[child] <= arr [i]) { break; } //否则将子节点的值给父节点 arr[i] = arr[child]; //以孩子为父节点,继续往下筛选 i = child ; child = 2 * child + 1; } arr[i] = temp; } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。