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

912.排序数组(堆排序)

目录

  • 题目
  • 解法
      • 1. 建立最大堆 (buildMaxHeap)
        • 从最后一个非叶子节点开始,依次调用 `maxHeapify`:
        • 最大堆完成:
      • 2. 堆排序过程
        • 第一轮:
        • 第二轮:
        • 第三轮:
        • 第四轮:
      • 最终排序结果

题目

给你一个整数数组 nums,请你将该数组升序排列。

你必须在 不使用任何内置函数 的情况下解决问题,时间复杂度为 O(nlog(n)),并且空间复杂度尽可能小。

解法

class Solution {
    void buildMaxHeap(vector<int>& nums) {
        int n = nums.size();
        for (int i = (n - 1) / 2; i >= 0; --i) {
            maxHeapify(nums, i, n);
        }
    }

    void maxHeapify(vector<int>& nums, int i, int n) {
        while (i * 2 + 1 < n) {
            // 代表当前 i 节点的左右儿子;
            // 超出数组大小则代表当前 i 节点为叶子节点,不需要移位
            int lSon = 2 * i + 1;
            int rSon = 2 * i + 2;
            int large = i;
            if (lSon < n && nums[lSon] > nums[i]) large = lSon;
            if (rSon < n && nums[rSon] > nums[large]) large = rSon;

            if (large != i) {
                swap(nums[i], nums[large]);
                // 迭代判断对应子节点及其儿子节点的大小关系
                i = large;
            } else {
                break;
            }
        }
    }

public:
    vector<int> sortArray(vector<int>& nums) {
        // heapSort 堆排序
        int n = nums.size();
        // 将数组整理成大根堆
        buildMaxHeap(nums);
        for (int i = n - 1; i >= 1; --i) {
            // 依次弹出最大元素,放到数组最后,当前排序对应数组大小 - 1
            swap(nums[0], nums[i]);
            --n;
            maxHeapify(nums, 0, n);
        }
        return nums;
    }
};


让我们用一个具体的例子来展示你提供的堆排序算法的排序过程。我们用数组 nums = [3, 5, 1, 10, 2] 作为示例。

1. 建立最大堆 (buildMaxHeap)

首先,我们需要将数组构建成一个最大堆:

  • 初始数组: [3, 5, 1, 10, 2]
从最后一个非叶子节点开始,依次调用 maxHeapify
  • 对于 i = 1:

    • 左子节点:5,右子节点:10
    • 10 > 5,所以 large 更新为 310 的索引)。
    • 交换 nums[1]nums[3],得到 [3, 10, 1, 5, 2]
    • 对于 i = 3,没有子节点,不需要再调整。
  • 对于 i = 0:

    • 左子节点:10,右子节点:1
    • 10 > 3,所以 large 更新为 1
    • 交换 nums[0]nums[1],得到 [10, 3, 1, 5, 2]
    • 现在 i = 1,左子节点为 5,右子节点为 2
    • 5 > 3,更新 large3
    • 交换 nums[1]nums[3],得到 [10, 5, 1, 3, 2]
    • 对于 i = 3,没有子节点,不需要再调整。
最大堆完成:

最大堆为 [10, 5, 1, 3, 2]

2. 堆排序过程

现在我们开始排序:

  • 初始数组:[10, 5, 1, 3, 2]
第一轮:
  • 交换 nums[0]nums[4](10 和 2),得到 [2, 5, 1, 3, 10]
  • 调用 maxHeapifyi = 0n = 4
    • 左子节点:5,右子节点:1
    • 5 > 2,更新 large1
    • 交换,得到 [5, 2, 1, 3, 10]
    • 对于 i = 1,左子节点为 3,更新 large3
    • 交换,得到 [5, 3, 1, 2, 10]
第二轮:
  • 交换 nums[0]nums[3](5 和 2),得到 [2, 3, 1, 5, 10]
  • 调用 maxHeapifyi = 0n = 3
    • 左子节点:3,右子节点:1
    • 3 > 2,更新 large1
    • 交换,得到 [3, 2, 1, 5, 10]
第三轮:
  • 交换 nums[0]nums[2](3 和 1),得到 [1, 2, 3, 5, 10]
  • 调用 maxHeapifyi = 0n = 2
    • 左子节点:2,无右子节点。
    • 2 > 1,更新 large1
    • 交换,得到 [2, 1, 3, 5, 10]
第四轮:
  • 交换 nums[0]nums[1](2 和 1),得到 [1, 2, 3, 5, 10]
  • 此时 n = 1,不需要再调用 maxHeapify

最终排序结果

经过上述步骤,最终得到的排序结果为 [1, 2, 3, 5, 10]

通过这个例子,你可以清楚地看到如何通过最大堆的建立和调整,完成堆排序的过程。


http://www.kler.cn/a/369148.html

相关文章:

  • 【mod分享】极品飞车9冬日mod,支持光追,想体验一把冬天的Rockport市吗
  • [翱捷]让SDK跑起来了
  • 技术成神之路:设计模式(二十一)外观模式
  • BERT的中文问答系统23
  • Tongweb7049m4+THS6010-6012版本 传真实ip到后端(by yjm+lwq)
  • w001基于SpringBoot的在线拍卖系统
  • Diffusion原理及代码实现
  • 【学术会议论文投稿】深度解码:机器学习与深度学习的界限与交融
  • 【STM32编码器】【STM32】
  • Linux学习笔记 | sudo命令的基本使用
  • 鸿蒙HarmonyOS————ArkTs介绍(1)
  • [免费]SpringBoot+Vue智慧校园(校园管理)系统[论文+源码+SQL脚本]
  • 面试经典 150 题 第三周代码
  • Java 基于 poi 和 itextpdf 实现 excel 转 pdf
  • 安卓自定义文本组件
  • 网络搜索引擎Shodan(3)
  • Javascript数据结构——哈希表
  • 什么是排列树?
  • 【单片机运行的原理及应用方向】
  • c#获取目录下所有文件
  • 51单片机应用开发(进阶)---外部中断(按键+数码管显示0-F)
  • 名城优企游学活动走进思腾合力:解析人工智能先行者的数字化之路
  • 记一次Esxi掉盘处理使用命令
  • [0152].第3节:IDEA中工程与模块
  • Python金色流星雨
  • 部署RocketMQ, 其实很简单 (带图, 附启动命令)