手写C++堆排序

手写快速排序:https://blog.csdn.net/weixin_42887343/article/details/119614233

1 堆排序原理

我们一般提到堆排序里的堆指的是二叉堆(binary heap)而不是堆栈的堆,二叉堆是一种完全二叉树,分为最大堆和最小堆(大根堆和小根堆),特点是父节点的值大于(小于)两个小节点的值。
在这里插入图片描述

2 快速排序函数

2.1 标准库

#include <algorithm>

标准库算法库中的堆相关函数

  • make_heap()用于把一个可迭代容器变成一个堆,默认是大顶堆。
  • sort_heap()是将堆进行排序,排序后,序列将失去堆的特性(子节点的键值总是小于或大于它的父节点)。
    make_heap(v.begin(),v.end());      
    sort_heap(v.begin(),v.end());   

make_heap 是按照给定的排序准则,把“最大”的元素排列到首位,而其他元素看上去并非有序:比如对序列 3 4 5 6 7 5 6 7 8 9 1 2 3 4 ,用make_heap 排序后为:9 8 6 7 7 5 5 3 6 4 1 2 3 4
如果你把这些元素转换为二叉树结构,就可以看出来每个节点的值都小于或等于其父节点值,此外heap 算法能够保证在对数时间内增加或移除一个元素,是实做优先队列的理想结构。

2.2 手写函数

void Heap_build(int data[],int root,int length)
{
    int lchild = root*2+1;              //根节点的左子结点下标
    if (lchild < length)                //左子结点下标不能超出数组的长度
    {
        int flag = lchild;              //flag保存左右节点中最大值的下标
        int rchild = lchild+1;          //根节点的右子结点下标
        if (rchild < length)            //右子结点下标不能超出数组的长度(如果有的话)
            if (data[rchild] > data[flag])    //找出左右子结点中的最大值
                flag = rchild;
        if (data[root] < data[flag])
        {
            std::swap(data[root],data[flag]);      //交换父结点和比父结点大的最大子节点
            Heap_build(data,flag,length);  //从此次最大子节点的那个位置开始递归建堆
        }
    }
}
void Heap_sort(int data[],int len)
{
    for (int i = len/2; i >= 0; --i)//从最后一个非叶子节点的父结点开始建堆
        Heap_build(data,i,len);
    for (int j = len-1; j > 0; --j)//j表示数组此时的长度,因为len长度已经建过了,从len-1开始
    {
        std::swap(data[0],data[j]);//交换首尾元素,将最大值交换到数组的最后位置保存
        Heap_build(data,0,j);//去除最后位置的元素重新建堆,此处j表示数组的长度,最后一个位置下标变为len-2
    }
}

3 demo代码

3.1 使用标准库函数

int main(int argc, char *argv[])
{
    vector<int> v;          //将myints复制到v
    for(int i=0;i<1000;i++)   //随机生成10个数并排序
        v.push_back(rand()%1000);

    cout << "\n init: \n";
    for (int i = 0;i < v.size();i ++) cout << ' ' << v[i];
    
    make_heap(v.begin(),v.end());      
    sort_heap(v.begin(),v.end());      
    
    cout << "\n\n out: \n";
    for (int i = 0;i < v.size();i ++) cout << ' ' << v[i];
    return 0;
}

3.2 使用手写函数

int main(int argc, char *argv[])
{
 	int arr[] = { 49, 38, 65, 97, 23, 22, 76, 1, 5, 8, 2, 0, -1, 22 };
    Heap_sort(arr, 13);
    for(int i = 0;i < 13;i ++)
        qDebug()<<arr[i];
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值