带你深入浅出新面经:十五、十大排序之堆排序

此为面经第十五谈!关注我,每日带你深入浅出一个新面经。

我们要了解面经要如何“说”

很重要!很重要!很重要!

我们通常采取总-分-总方式来阐述!(有些知识点,你可以去了解,但是面经并不是需要全部了解的)

码农不易,各位学者学到东西请点赞支持支持

排序算法部分可以记忆简单过程概述。

开始部分:

总:堆排序通过构建最大堆,然后逐步将堆顶元素与数组尾部元素交换并重新调整堆,直到完成排序。

分:

最好时间复杂度就是(n*k)

最差时间复杂度就是(n*k)

平均时间复杂度也是(n*k)

空间复杂度:n+k

稳定性:稳定。

#include <iostream>
#include <vector>
#include <algorithm> // 用于std::swap

using namespace std;

// 调整堆结构,确保堆的性质
void adjustHeap(vector<int>& arr, int i, int n) {
    int temp = arr[i]; // 暂存当前节点值
    for (int k = 2 * i + 1; k < n; k = k * 2 + 1) { // 从i节点的左子节点开始,也就是2i+1位置
        if (k + 1 < n && arr[k] < arr[k + 1]) k++; // 如果有右子节点且右子节点值较大,则选择右子节点
        if (arr[k] > temp) { // 如果子节点大于父节点
            arr[i] = arr[k]; // 将较大的子节点值放到父节点上
            i = k; // 继续向下调整
        } else break; // 子节点小于父节点,调整结束
    }
    arr[i] = temp; // 将暂存的值放到最终位置
}

// 堆排序函数
void heapSort(vector<int>& arr) {
    int n = arr.size(); // 获取数组长度
    for (int i = n / 2 - 1; i >= 0; i--) { // 从最后一个非叶子节点开始调整为最大堆
        adjustHeap(arr, i, n);
    }
    for (int j = n - 1; j > 0; j--) { // 交换堆顶元素与最后一个元素
        swap(arr[0], arr[j]); // 交换操作
        adjustHeap(arr, 0, j); // 重新调整堆
    }
}

// 主函数,用于测试堆排序
int main() {
    vector<int> arr = {3, 2, 5, 1, 7, 4, 6};
    cout << "Original array: ";
    for (int num : arr) cout << num << " ";
    cout << endl;

    heapSort(arr); // 调用堆排序函数

    cout << "Sorted array: ";
    for (int num : arr) cout << num << " ";
    cout << endl;

    return 0;
}

堆排序的步骤可以简化为以下几个关键点:

  1. 调整堆结构adjustHeap 函数用于将给定的数组元素调整为满足堆的性质,即父节点的值总是大于或等于其子节点的值(在最大堆中)。

  2. 构建最大堆:在 heapSort 函数中,从数组的最后一个非叶子节点开始,向下调用 adjustHeap 函数,逐步调整整个数组为一个最大堆。

  3. 交换并重新调整:将堆顶元素(最大值)与数组的最后一个元素交换,然后减少堆的有效长度,并重新调整堆结构以保持最大堆的性质。

  4. 重复交换与调整:重复步骤 3,直到堆的大小减少到只剩下一个元素,此时整个数组就变成了有序的。

总:排序可视化网站(建议打开看着代码来了解)Heap Sort Visualization

看着排序过程来理解代码实现会更好。

  学习链接:https://xxetb.xetslk.com/s/3Kif2D

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值