C++超详细分析优化排序算法之堆排序

C++超详细分析优化排序算法之堆排序

堆排序算法的思路

堆排序算法是一种树形选择排序算法。它的基本思想是:将待排序的序列构造成一个大根堆(或小根堆),此时,整个序列的最大(或最小)值就是堆顶的根节点。将它移走(其实就是将其与堆数组的末尾元素交换,此时末尾元素就是最大(或最小)值),然后将剩余的n-1个序列重新构造成一个堆,这样,每次找出最大(或最小)值的操作就可以比较快速的完成。

堆排序算法的具体步骤

  1. 将待排序序列构造成一个大根堆(或小根堆),并保存堆上的元素个数,设为heap_size;

c++
void build_max_heap(int a[], int len, int heap_size) {
for(int i = len / 2 - 1; i >= 0; i--) {
max_heapify(a, i, len, heap_size);
}
}

  1. 将堆顶元素与末尾元素进行交换,此时堆顶元素为序列的最大值,调整堆,在堆长度中减去1,将剩余元素再构造成堆,重复此步骤直到堆长度减为1;

c++
void heap_sort(int a[], int len) {
int heap_size = len;
build_max_heap(a, len, heap_size);
for(int i = len - 1; i >= 1; i--) {
swap(a[0], a[i]);
heap_size--;
max_heapify(a, 0, i, heap_size);
}
}

  1. 维护堆性质,使得以i为根节点的子树满足堆的定义。

c++
void max_heapify(int a[], int i, int len, int heap_size) {
int l = i * 2 + 1, r = i * 2 + 2, max_idx = i;
if(l < len && a[l] > a[max_idx]) max_idx = l;
if(r < len && a[r] > a[max_idx]) max_idx = r;
if(max_idx != i) {
swap(a[i], a[max_idx]);
--heap_size;
max_heapify(a, max_idx, len, heap_size);
}
}

堆排序算法的优化

  1. 尽可能的减少函数调用次数,使用inline关键字修饰重要的函数

```c++
inline void swap(int &a, int &b) {
int temp = a;
a = b;
b = temp;
}

inline void max_heapify(int a[], int i, int len, int heap_size) {
int l = i * 2 + 1, r = i * 2 + 2, max_idx = i;
if(l < len && a[l] > a[max_idx]) max_idx = l;
if(r < len && a[r] > a[max_idx]) max_idx = r;
if(max_idx != i) {
swap(a[i], a[max_idx]);
--heap_size;
max_heapify(a, max_idx, len, heap_size);
}
}
```

  1. 由于每次构造堆之前已经将最大值剔除,所以构造堆时只需要从剩余元素的一半开始,逐级向上调整即可

c++
void build_max_heap(int a[], int len, int heap_size) {
for(int i = len / 2 - 1; i >= 0; i--) {
max_heapify(a, i, len, heap_size);
}
}

  1. 在调整堆性质时,减少交换次数也能有效提升堆排序的效率

c++
void max_heapify(int a[], int i, int len, int heap_size) {
int l = i * 2 + 1, r = i * 2 + 2, max_idx = i;
if(l < len && a[l] > a[max_idx]) max_idx = l;
if(r < len && a[r] > a[max_idx]) max_idx = r;
if(max_idx != i) {
a[i] ^= a[max_idx] ^= a[i] ^= a[max_idx];
--heap_size;
max_heapify(a, max_idx, len, heap_size);
}
}

堆排序算法的时间复杂度及稳定性

堆排序算法的时间复杂度为 O(nlogn),它是不稳定的排序算法。

堆排序算法的示例说明

示例一

待排序序列:6,8,2,3,5,7,1

构造的大根堆:8,6,7,3,5,2,1

第一次排序后:1,6,7,3,5,2,8

构造的大根堆:7,6,1,3,5,2

第二次排序后:2,6,1,3,5,7

构造的大根堆:6,3,1,2,5

第三次排序后:5,3,1,2,6

构造的大根堆:3,2,1,5

第四次排序后:1,2,3,5

构造的大根堆:2,1,3

第五次排序后:1,2,3

构造的大根堆:2,1

第六次排序后:1,2

示例二

待排序序列:23,51,10,34,12,2,87,63

构造的大根堆:87,63,23,51,12,2,10,34

第一次排序后:34,63,23,51,12,2,10,87

构造的大根堆:63,51,23,34,12,2,10

第二次排序后:10,51,23,34,12,2,63

构造的大根堆:51,34,23,10,12,2

第三次排序后:2,34,23,10,12,51

构造的大根堆:34,12,23,2,10

第四次排序后:10,12,23,2,34

构造的大根堆:23,12,10,2

第五次排序后:2,12,10,23

构造的大根堆:12,2,10

第六次排序后:2,10,12

构造的大根堆:10,2

第七次排序后:2,10

构造的大根堆:10

第八次排序后:10

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++超详细分析优化排序算法之堆排序 - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • C语言超详细讲解排序算法上篇

    C语言超详细讲解排序算法上篇 简介 本文将介绍排序算法的基础知识和常见排序算法,包括冒泡排序、选择排序、插入排序。 排序算法是计算机科学中非常重要的算法之一,在实际开发中也经常用到。了解各种排序算法的特点和优缺点,可以帮助我们更好地应对实际问题。 基础知识 在介绍排序算法之前,有一些基础知识需要了解。 1. 时间复杂度 时间复杂度用来衡量一个算法所需要的计算…

    算法与数据结构 2023年5月19日
    00
  • C语言实现文件内容按行随机排列的算法示例

    下面我将为您详细介绍“C语言实现文件内容按行随机排列的算法示例”的完整攻略。 1、问题描述 首先,这个算法的问题描述是:实现一个按行随机排列文件内容的算法,要求结果能够尽可能地随机、均匀。 2、算法思路 针对这个问题,我们可以采用以下算法思路: 首先读取文件的全部内容,将其中的每一行存在一个字符串数组中; 然后采用洗牌算法(shuffle algorithm…

    算法与数据结构 2023年5月19日
    00
  • C/C++语言八大排序算法之桶排序全过程示例详解

    C/C++语言八大排序算法之桶排序全过程示例详解 什么是桶排序 桶排序(Bucket Sort)是一种线性排序算法,它的基本思想是将数组内的元素根据某个规则分配到若干个桶中,然后对每个桶内的元素进行排序,最终合并每个桶内的有序元素即可得到原数组的有序结果。 桶排序的主要应用场景是待排序元素的分布比较均匀的情况下,性能表现优于其他排序算法(例如快速排序、归并排…

    算法与数据结构 2023年5月19日
    00
  • 如何用JavaScript学习算法复杂度

    下面是关于如何用JavaScript学习算法复杂度的完整攻略: 1. 什么是算法复杂度? 算法复杂度指的是算法运行时间与输入数据规模之间的关系。通常使用大O表示法来表示算法的时间复杂度,即在最坏情况下,算法需要执行的基本操作次数和输入规模n的关系。从时间复杂度的角度出发,我们可以比较不同的算法及其优劣。 2. JavaScript中如何编写算法 JavaSc…

    算法与数据结构 2023年5月19日
    00
  • asp下几种常用排序算法

    我将为您详细讲解ASP下几种常用排序算法的完整攻略。 一、排序算法简介 排序算法是计算机科学中非常基础的算法之一。它是将一组数据中的元素按照某种规则进行排序的过程。排序算法是计算机程序设计的基础,它涉及到数据结构、算法、模式识别等计算机科学领域内的基础理论。 排序算法主要分为以下几种: 冒泡排序 选择排序 插入排序 快速排序 归并排序 本文将针对ASP下几种…

    算法与数据结构 2023年5月19日
    00
  • c语言冒泡排序法代码

    冒泡排序是常见的排序算法之一,它的基本思想是通过一系列的比较和交换来不断将列表中的最大值或最小值浮到列表的顶部(如冒泡一般),直到整个列表都有序排列。以下是一份c语言版本的冒泡排序代码: void bubbleSort(int arr[], int n){ int i, j; for (i = 0; i < n-1; i++){ for (j = 0;…

    算法与数据结构 2023年5月19日
    00
  • TF-IDF与余弦相似性的应用(一) 自动提取关键词

    下面我将详细讲解“TF-IDF与余弦相似性的应用(一) 自动提取关键词”的完整攻略。 什么是TF-IDF? TF-IDF(Term Frequency-Inverse Document Frequency)是一种常用于信息检索与分类中的文本特征提取方法,用于评估一段文本中词的重要程度。TF-IDF的核心思想就是:一个词在一篇文档中出现的频次(TF)越高,同时…

    算法与数据结构 2023年5月19日
    00
  • 如何利用Python动态展示排序算法

    首先,我们需要了解一下Python中常用的用于动态展示的库——matplotlib和pygame。 matplotlib是一个数据可视化库,它可以让我们轻松地创建各种静态和动态的图形,包括折线图、柱形图等等,而pygame则是一个开源的游戏开发库,它专用于创建游戏和动态图形。 接下来,我们就可以使用这两个库来展示排序算法了。 下面是一个示例,展示了如何使用m…

    算法与数据结构 2023年5月19日
    00
合作推广
合作推广
分享本页
返回顶部