八大排序算法----堆排序

堆排序的基本步骤:(以从大到小的顺序排序为例)

1.构建大顶堆(每个结点的值都大于或等于其左右孩子结点的值

2.排序:每次堆顶的元素取出来(整个堆中值最大 ),与最后一个节点做交换,使末尾元素最大

3.交换完之后,需要重新维护堆中剩下的其他节点,保证每次的堆顶都是最大值,重复2,3,直到序列完全有序

Code:

cpp 复制代码
//维护堆的性质
//大顶堆:父节点的左右孩子都比父节点小
//小顶堆:父节点的左右孩子都比父节点大
void heapify(vector<int>& nums, int n, int i)
{
    int large = i;//保存父节点
    int left = 2 * i + 1;//左孩子
    int right = 2 * i + 2;//右孩子
    //判断左孩子是否比父节点大? 大的话,就更新父节点的下标
    if (left<n && nums[left]>nums[large])
        large = left;
    //判断右孩子是否比父节点大? 大的话,就更新父节点的下标
    if (right<n && nums[right]>nums[large])
        large = right;
    //到此,已经找到了当前父节点和其左右孩子中最大的节点的下标
    //判断父节点的下标是否发生变化,如果不相等,说明左右孩子中有比父节点大的
    if (large != i)
    {
        //交换节点,维护大顶堆
        swap(nums[large], nums[i]);
        //继续维护剩下的节点
        heapify(nums, n, large);
    }
}
void heapsort(vector<int>& nums, int n)
{
    //建堆:从最后一个有孩子的父节点开始建立
    //这里为什么是i = n / 2 - 1? 因为左孩子的下标可以表示为2*i+1,此时最后一个孩子的下标为n-1
    //推导过来,找到最后一个有孩子的父节点的下标为n / 2 - 1
    for (int i = n / 2 - 1; i >= 0; i--)
    {
        heapify(nums, n, i);
    }
    //排序:将大顶堆的顶与最后一个叶子节点进行交换,也就是每次找到当前堆中最大的元素,放在数组的最后面
    for (int i = n - 1; i > 0; i--)
    {
        //交换
        swap(nums[i], nums[0]);
        //继续维护大顶堆中剩下节点,要始终保持是大顶堆的顺序
        heapify(nums, i, 0);
    }
}
int main()
{
    int n;
    cin >> n;
    vector<int> nums(n);
    for (int i = 0; i < n; i++)
    {
        cin >> nums[i];
    }
    heapsort(nums, n);
    cout << "按升序顺序排序" << endl;
    for (auto& i : nums)
    {
        cout << i << " ";
    }
    return 0;
}

这里如果要按照从小到大的顺序进行堆排序的话,只需要将维护堆的函数中if判断条件做一点小改动即可。

cpp 复制代码
void heapify(vector<int>& nums, int n, int i)
{
    int small = i;//保存父节点
    int left = 2 * i + 1;//左孩子
    int right = 2 * i + 2;//右孩子
    if (left<n && nums[left]<nums[small])
        small = left;
    if (right<n && nums[right]>nums[small])
        small = right;
    //判断父节点的下标是否发生变化,
    if (small != i)
    {
        //交换节点,维护大顶堆
        swap(nums[small], nums[i]);
        //继续维护剩下的节点
        heapify(nums, n, small);
    }
}

堆排序是不稳定的排序算法。

堆排序的时间复杂度:O(nlogn)

相关推荐
SweetCode几秒前
裴蜀定理:整数解的奥秘
数据结构·python·线性代数·算法·机器学习
ゞ 正在缓冲99%…14 分钟前
leetcode76.最小覆盖子串
java·算法·leetcode·字符串·双指针·滑动窗口
xuanjiong15 分钟前
纯个人整理,蓝桥杯使用的算法模板day2(0-1背包问题),手打个人理解注释,超全面,且均已验证成功(附带详细手写“模拟流程图”,全网首个
算法·蓝桥杯·动态规划
Zhichao_9732 分钟前
【UE5 C++课程系列笔记】33——商业化Json读写
c++·ue5
惊鸿.Jh34 分钟前
【滑动窗口】3254. 长度为 K 的子数组的能量值 I
数据结构·算法·leetcode
明灯L34 分钟前
《函数基础与内存机制深度剖析:从 return 语句到各类经典编程题详解》
经验分享·python·算法·链表·经典例题
碳基学AI40 分钟前
哈尔滨工业大学DeepSeek公开课:探索大模型原理、技术与应用从GPT到DeepSeek|附视频与讲义免费下载方法
大数据·人工智能·python·gpt·算法·语言模型·集成学习
补三补四44 分钟前
机器学习-聚类分析算法
人工智能·深度学习·算法·机器学习
独好紫罗兰1 小时前
洛谷题单3-P5718 【深基4.例2】找最小值-python-流程图重构
开发语言·python·算法
云边有个稻草人1 小时前
【C++】第八节—string类(上)——详解+代码示例
开发语言·c++·迭代器·string类·语法糖auto和范围for·string类的常用接口·operator[]