MyTinySTL中的排序算法:heap_sort实现

MyTinySTL中的排序算法:heap_sort实现

【免费下载链接】MyTinySTL Achieve a tiny STL in C++11 【免费下载链接】MyTinySTL 项目地址: https://gitcode.com/gh_mirrors/my/MyTinySTL

在C++标准模板库(STL)中,堆排序(Heap Sort)是一种高效的排序算法,它利用堆(Heap)这种数据结构来实现排序。MyTinySTL作为一个精简版的STL实现,也提供了完整的堆排序功能。本文将详细介绍MyTinySTL中堆排序的实现原理和使用方法。

堆排序的基本原理

堆排序是一种基于比较的排序算法,它的基本思想是:

  1. 将待排序的数组构建成一个最大堆(Max Heap)
  2. 重复以下步骤,直到堆的大小为1:
    • 将堆顶元素(最大值)与堆的最后一个元素交换
    • 减小堆的大小,将剩余元素重新构建成最大堆
  3. 最终得到的数组就是排序好的数组

堆排序的时间复杂度为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_heappush_heappop_heapsort_heap四个函数的协作,实现了高效的堆排序算法。这些函数的实现位于MyTinySTL/heap_algo.h文件中,通过模板技术提供了良好的通用性。

堆排序作为一种高效的排序算法,在实际应用中具有广泛的用途。通过学习MyTinySTL中的实现,我们不仅可以深入理解堆排序的原理,还可以学习到STL算法的设计思想和实现技巧。

如果你想了解更多关于MyTinySTL的实现细节,可以查阅项目中的测试代码,如Test/algorithm_test.h中包含了各种算法的测试用例。

【免费下载链接】MyTinySTL Achieve a tiny STL in C++11 【免费下载链接】MyTinySTL 项目地址: https://gitcode.com/gh_mirrors/my/MyTinySTL

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

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

抵扣说明:

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

余额充值