堆排序学习笔记

Posted 药菌

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了堆排序学习笔记相关的知识,希望对你有一定的参考价值。

1.堆介绍

堆的物理存储结构是一维数组,逻辑存储结构是完全二叉树,它满足下列性质:

  • 堆中任意节点的值总是不大于(不小于)其子节点的值;

  • 堆总是一棵完全树;

将任意节点不大于其子节点的堆叫做最小堆或小根堆,而将任意节点不小于其子节点的堆叫做最大堆或大根堆。二叉堆一般都通过"数组"来实现。数组实现的二叉堆,父节点和子节点的位置存在一定的关系。假设"第一个元素"在数组中的索引为 0 的话,则父节点和子节点的位置关系如下:

  • 索引为i的左孩子的索引是 (2*i+1);

  • 索引为i的左孩子的索引是 (2*i+2);

最大堆和最小堆示意图如下:

2.堆排序过程

堆排序是选择排序的一种,主要包括建堆调整堆两个过程。首先是根据序列元素构建大顶堆。此时,整个序列的最大值就是堆顶的根节点。然后将根节点最后一个节点进行交换,再将前面剩下的n-1个节点继续进行堆调整的过程,然后再将根节点取出,这样循环一直到所有节点都取出。堆排序过程的时间复杂度是O(nlgn)也是不稳定排序算法。

3.程序实现

 1#include <iostream>
2#include <ctime>
3#include <vector>
4
5using namespace std;
6
7//输出函数
8template <class T>
9void printArr(T *arrint length)
10{

11    for (int i = 0; i < length; ++i)
12    {
13        cout << arr[i] << " ";
14    }
15    cout << endl;
16}
17
18
19//交换函数
20template <class T>
21void swap(T *aT *b)
22{

23    T temp;
24    temp = *a;
25    *a = *b;
26    *b = temp;
27
28}
29
30//建立最大堆函数
31void adjust(int arr[], int length, int index)
32
{
33    int left = 2 * index + 1;
34    int right = 2 * index + 2;
35    int maxIdx = index;
36
37    if (left < length&&arr[left] > arr[maxIdx])
38    {
39        maxIdx = left;
40    }
41    if (right < length&&arr[right] > arr[maxIdx])
42    {
43        maxIdx = right;
44    }
45
46    if (maxIdx != index)// 如果maxIdx的值有更新
47    {
48        swap(arr[maxIdx], arr[index]);
49        adjust(arr, length, maxIdx);// 递归调整其他不满足堆性质的部分
50    }
51}
52
53//堆排序
54void HeapSort(int *arr, int length)
55
{
56    /*
57    * 从最后一个非叶结点开始.对每一个非叶结点进行最大堆调整
58    */

59    for (int i = length / 2 - 1; i >= 0; i--)
60    {
61        adjust(arr, length, i);
62    }
63
64    for (int j = length - 1; j >= 0; j--)
65    {
66        swap(arr[j], arr[0]);// 将当前最大的元素放置到数组末尾
67        cout << "第" << j << "次排序结果:" << endl;
68        printArr<int>(arr, 10);
69        adjust(arr, j, 0); // 将未完成排序的部分继续进行堆排序
70    }
71}
72
73int main()
74
{
75    int a[] = { 10123243539087100 };
76
77    cout << "堆排序前:" << endl;
78    printArr<int>(a, 10);
79
80    clock_t ibegin, iend;
81    ibegin = clock();
82    HeapSort(a, 10);
83    iend = clock();
84    cout << "用时" << iend - ibegin << "毫秒" << endl;
85
86    cout << "堆排序后:" << endl;
87    printArr<int>(a, 10);
88
89    system("pause");
90    return 0;
91}

4.运行结果

可以看到,每运行一次,便将最大的元素交换到序列末尾,n-1次后便可排序完成。

参考:https://blog.csdn.net/lzuacm/article/details/52853194,点击阅读原文”阅读。


以上是关于堆排序学习笔记的主要内容,如果未能解决你的问题,请参考以下文章

数据结构学习笔记——选择排序(简单选择排序和堆排序)

数据结构学习笔记——选择排序(简单选择排序和堆排序)

堆排序学习笔记

数据结构学习笔记——选择排序(简单选择排序和堆排序)

学习笔记:堆排序

数据结构学习笔记-排序/队/栈/链/堆/查找树/红黑树