Java堆排序

堆排序,顾名思义,就是要用到堆的知识。其基本的原理也就是选择排序,知识不再使用遍历的方式查找无序区间的最大数,而是用堆来来选择无序区间中的最大值。但是需要注意的是,排升序需要用到最大堆,排降序需要用到最小堆。

排序流程图

堆排序的排序流程图

排序思想

在讲解堆排序思想前,需要先知道一些关于堆排序的知识:
1.堆在逻辑上事一颗完全二叉树。
2.堆在物理上是保存在数组中(按照层序遍历顺序保存)。
3.最大堆:每一个节点的值都大于或等于其两个子节点的值。
4.最大堆的下沉操作:为满足最大堆的性质,需要将指定位置的数在二叉树的逻辑上,向下交换到合适的位置。
5.最大堆的构建:从层序遍历中最后一个非叶子节点开始,每个节点执行下沉操作,则可完成二叉树的构建。
在堆排序中,需要用到以上的有关于堆的知识,此时来讲解堆排序:
1.将无序数组构建为最大堆的形式,此时堆顶的数就是当前无序数组中最大的数。
2.将无序数组的最后一个数和第一个数交换,则最大的数被交换到了无序数组的最后,成为了有序数组的一部分。
3.将交换后的第一个数(也就是刚刚无序数组的最后一个数)进行下沉操作,以继续满足最大堆的性质。
4.重复上述的操作,直到整个数组排序完成。

排序代码

public static void heapSort(int[] arr){
	//从最后一个非叶子节点开始下沉操作,构建最大堆
    for (int i = (arr.length - 1 - 1) / 2; i >= 0; i--){
        siftDown(arr, i, arr.length);
    }
    //对数组进行交换和下沉操作
    for (int i = arr.length - 1; i > 0; i--){
        swap(arr, 0, i);
        siftDown(arr, 0, i);
    }
}
//下沉操作
private static void siftDown(int[] arr, int i, int length) {
	//保证此节点有左节点
    while (2 * i + 1 < length){
    	//左节点的索引
        int j = (i << 1) + 1;
        //判断是否有右节点,并筛选出两节点的最大值所在的索引
        if (j + 1 < length && arr[j + 1] > arr[j]){
            ++j;
        }
        //若节点的值小于节点的最大值,则结束循环
        if (arr[i] > arr[j]){
            break;
        }
        //交换两节点的值,并更改当前节点的索引
        swap(arr, i, j);
        i = j;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值