当前位置: 首页 > news >正文

【排序算法】之堆排序

堆排序的基本思想是:

具体可看视频演示:堆排序

- 1、将带排序的序列构造成一个大(小)顶堆,根据大顶堆的性质,当前堆的根节点(堆顶)就是序列中最大的元素;
		buildHeap();
- 2、将堆顶元素和最后一个元素交换交换一次,i--一次,然后将剩下的节点重新构造成一个大顶堆;
		swap() + buildHeap()
- 3、重复步骤2,如此反复,从第一次构建大顶堆开始,每一次构建,我们都能获得一个序列的最大值,然后把它放到大顶堆的尾部。最后,就得到一个有序的序列了。
		heapSort();
代码演示
/**
 * 堆排序 对简单选择排序的优化
 */
public class HeapSort {
    //堆排序
    public static void heapSort(int[] arr) {
        if (arr == null || arr.length == 0) {
            return;
        }
        int len = arr.length;
        //1.构件大顶堆,把数组变成一个大顶堆结构的数组;
        //要知道数组的长度
        buildHeap(arr, len);
        //2.交换堆顶元素与末尾元素 剩下的元素重新构成一个大顶堆
        for (int i = len - 1; i >= 0; i--) { //每交换一次末位位置要-1
            //4.
            swap(arr, 0, i);
            len--;
            //每次调整的时候默认len-1;因为每次最后位置的数就是我们所求得最大的
            heapify(arr, 0, len);
        }
    }

    //3.heapify真正用来调整大顶堆的方法
    /**
     * @param arr 待整理的数组
     * @param i   每次整理时候,当前非叶子节点的位置
     * @param len   每次整理数组时,节点的个数
     */
    private static void heapify(int[] arr, int i, int len) {
        if (i>=len){
            return;
        }
        //给了一个非叶子节点i的位置 我们首先找到它的两个孩子
        int left = 2 * i + 1;
        int right = 2 * i + 2;
        int max = i;//假设父节点i是最大值的位置
        //下面进行判断找到最大值所在的节点位置 同时要保证节点不会越界
        if (left < len && arr[left] > arr[max]) {
            max = left;
        }
        if (right < len && arr[right] > arr[max]) {
            max = right;
        }
        //找出最大值后就进行交换
        if (max!=i){
            // 如果最大值位置不是当前非叶子节点的位置,那么就把当前节点和最大值的子节点值互换
            swap(arr, i, max);
            // 因为互换之后,子节点的值变了,该子节点可能也有自己的子节点,仍需要再次调整。
            heapify(arr, max,len);
        }
    }
    //1.构造大顶堆
    private static void buildHeap(int[] arr) {
        // 从最后一个非叶节点开始向前遍历,调整节点,使整个数组成为大顶堆
       //数组的长度/2 - 1 就是:第一个非零节点的位置
        int n=arr.length;
        for (int i = n / 2 - 1; i >= 0; i--) {
            //3.
            heapify(arr, i, n);
        }

    }
    //4.交换元素
    private static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

    public static void main(String[] args) {
        int[] arr={23,45,1,5,67,88,99,9,2,3};
        heapSort(arr);
        for (int res : arr) {
            System.out.print(res+" ");
        }
    }
}

相关文章:

  • L1-025:正整数A+B
  • 深入理解RBAC权限系统
  • K8s 入门指南(一):单节点集群环境搭建
  • Spring--10--Spring Bean的生命周期
  • mac安装elasticsearch8.x
  • Android 顶部对齐宽度撑满高度等比例缩放及限制最大最小高度
  • 从互联网到云计算再到 AI 原生,百度智能云数据库的演进
  • MySQL执行语句 Table ‘mysql.servers‘ doesn‘t exist
  • Python爬取酷我音乐
  • 贵州开放大学形成性考核 平时作业 参考试题
  • Error opening file for writing报错解决
  • RocketMQ-RocketMQ高性能核心原理节点(流程图)
  • C++基础 -42- STL库之list链表
  • python:六种算法(DBO、RFO、WOA、GWO、PSO、GA)求解23个测试函数(python代码)
  • 从零开始搭建企业管理系统(六):RBAC 权限管理设计
  • 阿里云docker加速
  • 代码随想录 96. 不同的二叉搜索树
  • el-table 表格多选(后端接口搜索分页)实现已选中的记忆功能。实现表格数据和已选数据(前端分页)动态同步更新。
  • 结合ColorUI组件开发微信小程序
  • 公有云迁移研究——AWS Route53
  • 新片|《碟中谍8:最终清算》定档5月30日
  • 哈马斯官员:若实现永久停火,可交出加沙地带控制权
  • 1至4月全国铁路发送旅客14.6亿人次,创同期历史新高
  • 美叙领导人25年来首次会面探索关系正常化,特朗普下令解除对叙经济制裁
  • 七部门:进一步增强资本市场对于科技创新企业的支持力度
  • 马上评|“为偶像正名”的正确做法是什么