MyTinySTL中的排序算法:heap_sort实现
【免费下载链接】MyTinySTL Achieve a tiny STL in C++11 项目地址: https://gitcode.com/gh_mirrors/my/MyTinySTL
在C++标准模板库(STL)中,堆排序(Heap Sort)是一种高效的排序算法,它利用堆(Heap)这种数据结构来实现排序。MyTinySTL作为一个精简版的STL实现,也提供了完整的堆排序功能。本文将详细介绍MyTinySTL中堆排序的实现原理和使用方法。
堆排序的基本原理
堆排序是一种基于比较的排序算法,它的基本思想是:
- 将待排序的数组构建成一个最大堆(Max Heap)
- 重复以下步骤,直到堆的大小为1:
- 将堆顶元素(最大值)与堆的最后一个元素交换
- 减小堆的大小,将剩余元素重新构建成最大堆
- 最终得到的数组就是排序好的数组
堆排序的时间复杂度为O(n log n),空间复杂度为O(1),是一种原地排序算法。
MyTinySTL中的堆算法模块
MyTinySTL将堆相关的算法集中实现于MyTinySTL/heap_algo.h文件中,包含四个核心函数:
make_heap: 将一段序列转换为堆push_heap: 向堆中添加元素并保持堆的性质pop_heap: 从堆中移除顶部元素并保持堆的性质sort_heap: 对堆进行排序
make_heap函数实现
make_heap函数用于将一段序列转换为堆结构,其实现代码如下:
template <class RandomIter>
void make_heap(RandomIter first, RandomIter last)
{
mystl::make_heap_aux(first, last, distance_type(first));;
}
template <class RandomIter, class Distance>
void make_heap_aux(RandomIter first, RandomIter last, Distance*)
{
if (last - first < 2)
return;
auto len = last - first;
auto holeIndex = (len - 2) / 2;
while (true)
{
// 重排以 holeIndex 为首的子树
mystl::adjust_heap(first, holeIndex, len, *(first + holeIndex));
if (holeIndex == 0)
return;
holeIndex--;
}
}
该函数从最后一个非叶子节点开始,通过adjust_heap函数对每个节点进行调整,使整个序列满足堆的性质。
sort_heap函数实现
sort_heap函数是实现堆排序的核心函数,其代码如下:
template <class RandomIter>
void sort_heap(RandomIter first, RandomIter last)
{
// 每执行一次 pop_heap,最大的元素都被放到尾部,直到容器最多只有一个元素,完成排序
while (last - first > 1)
{
mystl::pop_heap(first, last--);
}
}
sort_heap函数通过不断调用pop_heap函数,将堆顶元素(当前最大值)移到序列末尾,然后缩小堆的范围,直到整个序列排序完成。
pop_heap函数实现
pop_heap函数用于移除堆顶元素并保持堆的性质,其实现依赖于adjust_heap函数:
template <class RandomIter>
void pop_heap(RandomIter first, RandomIter last)
{
mystl::pop_heap_aux(first, last - 1, last - 1, *(last - 1), distance_type(first));
}
template <class RandomIter, class T, class Distance>
void pop_heap_aux(RandomIter first, RandomIter last, RandomIter result, T value,
Distance*)
{
// 先将首值调至尾节点,然后调整[first, last - 1)使之重新成为一个 max-heap
*result = *first;
mystl::adjust_heap(first, static_cast<Distance>(0), last - first, value);
}
adjust_heap函数实现
adjust_heap函数是堆调整的核心,实现了堆的下溯(percolate down)和上溯(percolate up)过程:
template <class RandomIter, class T, class Distance>
void adjust_heap(RandomIter first, Distance holeIndex, Distance len, T value)
{
// 先进行下溯(percolate down)过程
auto topIndex = holeIndex;
auto rchild = 2 * holeIndex + 2;
while (rchild < len)
{
if (*(first + rchild) < *(first + rchild - 1))
--rchild;
*(first + holeIndex) = *(first + rchild);
holeIndex = rchild;
rchild = 2 * (rchild + 1);
}
if (rchild == len)
{ // 如果没有右子节点
*(first + holeIndex) = *(first + (rchild - 1));
holeIndex = rchild - 1;
}
// 再执行一次上溯(percolate up)过程
mystl::push_heap_aux(first, holeIndex, topIndex, value);
}
堆排序的完整使用示例
以下是使用MyTinySTL中堆排序算法的完整示例:
#include "MyTinySTL/vector.h"
#include "MyTinySTL/heap_algo.h"
#include <iostream>
int main() {
mystl::vector<int> v = {3, 1, 4, 1, 5, 9, 2, 6};
// 将vector转换为堆
mystl::make_heap(v.begin(), v.end());
// 对堆进行排序
mystl::sort_heap(v.begin(), v.end());
// 输出排序结果
for (auto i : v) {
std::cout << i << " ";
}
// 输出:1 1 2 3 4 5 6 9
return 0;
}
堆排序算法的性能测试
MyTinySTL项目中提供了算法性能测试工具,可以在Test/algorithm_performance_test.h文件中找到相关测试代码。通过这些测试,我们可以验证堆排序算法的实际性能表现。
总结
MyTinySTL中的堆排序实现遵循了STL的设计理念,通过make_heap、push_heap、pop_heap和sort_heap四个函数的协作,实现了高效的堆排序算法。这些函数的实现位于MyTinySTL/heap_algo.h文件中,通过模板技术提供了良好的通用性。
堆排序作为一种高效的排序算法,在实际应用中具有广泛的用途。通过学习MyTinySTL中的实现,我们不仅可以深入理解堆排序的原理,还可以学习到STL算法的设计思想和实现技巧。
如果你想了解更多关于MyTinySTL的实现细节,可以查阅项目中的测试代码,如Test/algorithm_test.h中包含了各种算法的测试用例。
【免费下载链接】MyTinySTL Achieve a tiny STL in C++11 项目地址: https://gitcode.com/gh_mirrors/my/MyTinySTL
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



