堆排序--C++实现

1. 简介

堆排序利用的是堆序性,最小堆进行从大到小的排序。

先建初堆,保证堆序性。将堆顶元素与最后一个元素交换,

就将当前堆中的最大(小)的元素放到了最后后。堆大小递减,再重新调整堆选出第二大,重复上述过程。

2. 实现

2.1 建初堆

由于堆具有递归性,即以根节点的所有子树都是一个堆。

我们需要从下往上调整堆。即从完全二叉树的最大非叶子节点开始调整堆,直到根节点。

这样才能保证堆序性。

对于数组3,4,1,2,5 ,建初堆的过程。

  • 代码
cpp 复制代码
template<typename T>
void adj_heap(std::vector<T> &arr,std::size_t rt, std::size_t bd) {

    T v = arr[rt];
    std::size_t child;
    std::size_t i;

    for (i = rt; i < bd; i = child) {

        child = i * 2 + 1;
        if ( child + 1 < bd && arr[child + 1] < arr[child])
            ++child;

        if (child >= bd || v <= arr[child] ) {
            break;
        }
        else{
            arr[i] = arr[child];
        }

    }

    arr[i] = v;
}


template<typename T>
void make_orig_heap(std::vector<T> &arr, std::size_t sz) {

    for (std::size_t i = sz/2 - 1; i != -1; --i){
        adj_heap(arr, i, sz);
    }
}
2.2 堆排序

建立初始堆后,我们就确定了最小(大)的元素。

将该元素与最后位置交换,并将堆大小 - 1。

我们就又得到了一个未调整的堆。我们重复调整堆和交换元素的过程,直到最后堆大小为1。

所以,最小堆进行排序形成的序列是从大到小。

过程如图

  • 代码
cpp 复制代码
template<typename T>
void heap_sort(std::vector<T> &arr, std::size_t sz) {

    if ( 0 == sz)
        return ;

    make_orig_heap(arr, sz);
    
    

    for (std::size_t i = sz - 1; i > 0; --i) {
        T last = arr[i];
        arr[i] = arr[0];
        arr[0] = last;
        adj_heap(arr, 0, i);
    }

}
相关推荐
故事和你9111 小时前
洛谷-【动态规划2】线性状态动态规划4
开发语言·数据结构·c++·算法·动态规划·图论
不吃土豆的马铃薯11 小时前
Socket 网络编程实战教程
linux·服务器·开发语言·网络·c++·算法
零号全栈寒江独钓11 小时前
c++跨平台实现日志重定向
linux·c++·windows
小成2023032026512 小时前
从C到C++
开发语言·c++
折哥的程序人生 · 物流技术专研12 小时前
《Java 100 天进阶之路》第39篇:Java泛型方法的定义和使用
java·开发语言·后端·面试·求职招聘
天天进步201512 小时前
Tunnelto 源码解析 #1:从 tunnelto --port 8000 看内网穿透的完整链路
开发语言
啄缘之间12 小时前
8.【学习】工业级详细接口约束&覆盖率
开发语言·笔记·学习·uvm·sv
Chase_______12 小时前
【Java基础核心知识点全解·09】Java 内存布局与垃圾回收详解:栈、堆、栈帧、GC Roots 与对象回收
java·开发语言
江南十四行12 小时前
并发编程(四)
开发语言·python
葱卤山猪12 小时前
C++17 联合体
开发语言·c++