堆排序算法——C++

 堆排序分为大顶堆排序和小顶堆排序,两者时间复杂度是O(nlogn),空间复杂度是O(1)的常量级临时变量,是不稳定排序算法。

大顶堆主要实现思想:

1.初始化构建大顶堆

void initMaxHeap(vector<int>& nums);

2.将大顶堆的根(最大值)交换到数组最后面,然后将待排序数组长度减一后重新构建大根堆

void buildMaxHeap(vector<int>& nums, int waitSortNode, int waitSortNums);

3.依次循环步骤2,直到待排序数组长度为0,完成大顶堆排序

for(int i=arr.size() - 1; i>0; --i) {swap(arr[0], [i]); buildMaxHeap(arr, 0, i);} // 经过初始化后的大顶堆基本有序,只需要将交换后的根节点依次向下找到合适位置即可

for (int i = nums.size() - 1; i > 0; --i) // 初始化完后最大值交换到数组最后面,然后对根节点待排序非叶子节点进行排序
{
    std::swap(nums[0], nums[i]);
    buildMaxHeap(nums, 0, i); // 这里只有根节点是需要排序的,因为前面已经初始化过大顶堆,是基本有序的,只有交换后的根节点是需要排序
}

注意:大顶堆每一个子节点都是一个大顶堆,所以交换后一定要重建大顶堆,将交换后的值摆放到合适位置

下面是实现选择排序算法代码

Sorts.h

#pragma once

#include <iostream>
#include <vector>

using namespace std;

struct Sorts {
    void maxHeap(vector<int>& nums);

    void print(vector<int>& nums);

private:
    void buildMaxHeap(vector<int>& nums, int waitSortNode, int waitSortNums);
    void initMaxHeap(vector<int>& nums);
};

Sorts.cpp

#include "Sorts.h"

void Sorts::maxHeap(vector<int>& nums)
{
    initMaxHeap(nums); // 初始化大顶堆
    for (int i = nums.size() - 1; i > 0; --i) // 初始化完后最大值交换到数组最后面,然后对根节点待排序非叶子节点进行排序
    {
        std::swap(nums[0], nums[i]);
        buildMaxHeap(nums, 0, i); // 这里只有根节点是需要排序的,因为前面已经初始化过大顶堆,是基本有序的,只有交换后的根节点是需要排序
    }
}

void Sorts::print(vector<int>& nums)
{
    for (const auto& it : nums)
        cout << it << ",";
    cout << endl;
}


void Sorts::buildMaxHeap(vector<int>& nums, int waitSortNode, int waitSortNums)
{
    int leftIndex = 2 * waitSortNode + 1;
    int rightIndex = leftIndex + 1;
    int maxIndex = waitSortNode; // 最小二叉树中最大值下标
    if (leftIndex < waitSortNums && nums[maxIndex] < nums[leftIndex]) // 左子节点在待排序数组内才比较
        maxIndex = leftIndex;
    if (rightIndex < waitSortNums && nums[maxIndex] < nums[rightIndex]) // 右子节点在待排序数组内才比较
        maxIndex = rightIndex;
    if (maxIndex != waitSortNode) // 如果根节点不是最大值,则交换,交换后在进行自身子节点大根堆排序
    {
        std::swap(nums[maxIndex], nums[waitSortNode]);
        buildMaxHeap(nums, maxIndex, waitSortNums);
    }
}

void Sorts::initMaxHeap(vector<int>& nums)
{
    // 从完全二叉树的最后一个非叶子依次比较,如果交换则保证交换后的子节点满足大顶堆性质
    for (int i = nums.size()/2 - 1; i >= 0; --i)
        buildMaxHeap(nums, i, nums.size()); // 剩余大小主要作用是判断节点子节点是否在待排序的数组里(i<waitSortNums)
}

main.cpp

 #include <vector>
#include "Sorts.h"

using namespace std;

int main()
{
    vector<int> nums = { 2,0,1,6,8,10,5,99,87,333,2,0,1 };
    Sorts sorts;
    sorts.print(nums);
    sorts.maxHeap(nums);
    sorts.print(nums);

	return 1;
}

输出结果:

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

三公子Tjq

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值