1. 堆排序快速排序归并排序一样都是时间复杂度为O(N*logN)的几种常见排序方法。学习堆排序前,先讲解下什么是数据结构中的二叉堆。

二叉堆的定义

二叉堆是完全二叉树或者是近似完全二叉树。

二叉堆满足二个特性:

1)父结点的键值总是大于或等于(小于或等于)任何一个子节点的键值。

2)每个结点的左子树和右子树都是一个二叉堆(都是最大堆或最小堆)。

当父结点的键值总是大于或等于任何一个子节点的键值时为最大堆。当父结点的键值总是小于或等于任何一个子节点的键值时为最小堆

堆分为大顶堆和小顶堆,其中下图(1)中是大顶堆,(2)为小顶堆

2.   堆排序的思想

利用大顶堆(小顶堆)堆顶记录的是最大关键字(最小关键字)这一特性,使得每次从无序中选择最大记录(最小记录)变得简单。

其基本思想为(大顶堆):

1)将初始待排序关键字序列(R1,R2....Rn)构建成大顶堆,此堆为初始的无序区;

2)将堆顶元素R[1]与最后一个元素R[n]交换,此时得到新的无序区(R1,R2,......Rn-1)和新的有序区(Rn),且满足R[1,2...n-1]<=R[n];

3)由于交换后新的堆顶R[1]可能违反堆的性质,因此需要对当前无序区(R1,R2,......Rn-1)调整为新堆,然后再次将R[1]与无序区最后一个元素交换,得到新的无序区(R1,R2....Rn-2)和新的有序区(Rn-1,Rn)。不断重复此过程直到有序区的元素个数为n-1,则整个排序过程完成。

下面举例说明(大顶堆):

给定一个整形数组a[]={16,7,3,20,17,8},对其进行堆排序。

1)首先根据该数组元素构建一个完全二叉树,得到

 2)然后需要构造初始堆,则从最后一个非叶节点开始调整,调整过程如下:

20和16交换后导致16不满足堆的性质,因此需重新调整

这样就得到了初始堆。

即每次调整都是从父节点、左孩子节点、右孩子节点三者中选择最大者跟父节点进行交换(交换之后可能造成被交换的孩子节点不满足堆的性质,因此每次交换之后要重新对被交换的孩子节点进行调整)。有了初始堆之后就可以进行排序了。
3)

此时3位于堆顶不满堆的性质,则需调整继续调整

其实就是每次把堆顶元素和最后没交换过的子节点元素交换,然后将此子节点之前的二叉树重新排序,变成大顶堆。

如果按递增排序,需要用到大顶堆,每次把堆顶(无序堆最大值)放到有序堆前面,重新得到无序区大顶堆;

如果按递减排序,需要用到小顶堆,每次把堆顶(无序堆最小值)放到有序堆前面,重新得到无序区小顶堆;

程序如下(包含递增和递减):

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 using System.IO;
  6
  7 namespace conHeapSort
  8 {
  9     class HeapSort
 10     {
 11         private static Boolean Asce = true;//heap sorted by ascending order
 12         private static Boolean Desc = false;//heap sorted by descending order
 13         static void Main(string[] args)
 14         {
 15             List<int> input = new List<int>();
 16             HeapSort exap = new HeapSort();
 17             String str;
 18
 19             input.Add(0);//start from index one
 20             str = Console.ReadLine();
 21             while(str != "exit"){
 22                 input.Add(Int32.Parse(str));
 23                 str = Console.ReadLine();
 24             }
 25
 26             exap.SortHeap(input, Desc);
 27             for (int i = 1; i < input.Count; i++ )
 28             {
 29                 Console.WriteLine(input[i].ToString());
 30             }
 31         }
 32         void SortHeap(List<int> data, Boolean order)
 33         {
 34             BuildHeap(data, order);
 35
 36             if (order)
 37             {
 38                 for (int i = data.Count - 1; i >= 1; i--)
 39                 {
 40                     Swap(data, 1, i); //exchange between index 1 and index i
 41                     MaxHeap(data, 1, i - 1); //get max heap
 42                 }
 43             }
 44             else
 45             {
 46                 for (int i = data.Count - 1; i >= 1; i--)
 47                 {
 48                     Swap(data, 1, i);//exchange between index 1 and index i
 49                     MinHeap(data, 1, i - 1); //get min heap
 50                 }
 51             }
 52         }
 53         void BuildHeap(List<int> data, Boolean order)
 54         {
 55             if (order) //make maximal heap
 56             {
 57                 for (int i = data.Count / 2; i >= 1; i--)
 58                 {
 59                     MaxHeap(data, i, data.Count - 1); //initialize
 60                 }
 61             }
 62             else //make minimal heap
 63             {
 64                 for (int i = data.Count / 2; i >= 1; i--)
 65                 {
 66                     MinHeap(data, i, data.Count - 1);//initialize
 67                 }
 68             }
 69         }
 70         //get max heap
 71         void MaxHeap(List<int> data, int i, int size)
 72         {
 73             int lchild = 2 * i;
 74             int rchild = lchild + 1;
 75             int max = i;
 76             if (i <= size / 2)
 77             {
 78                 if (lchild <= size && data[lchild] > data[max])
 79                 {
 80                     max = lchild;
 81                 }
 82                 if (rchild <= size && data[rchild] > data[max])
 83                 {
 84                     max = rchild;
 85                 }
 86                 if (max != i)
 87                 {
 88                     Swap(data, i, max); //exchange child and parent node
 89                     MaxHeap(data, max, size); //continue to adjust
 90                 }
 91             }
 92         }
 93         //get min heap
 94         void MinHeap(List<int> data, int i, int size)
 95         {
 96             int lchild = 2 * i;
 97             int rchild = lchild + 1;
 98             int min = i;
 99             if (i <= size / 2)
100             {
101                 if (lchild <= size && data[lchild] < data[min])
102                 {
103                     min = lchild;
104                 }
105                 if (rchild <= size && data[rchild] < data[min])
106                 {
107                     min = rchild;
108                 }
109                 if (min != i)
110                 {
111                     Swap(data, i, min);//exchange child and parent node
112                     MinHeap(data, min, size);
113                 }
114             }
115         }
116         //exchange index1 and index2 in data
117         void Swap(List<int> data, int index1, int index2)
118         {
119             int temp = data[index2];
120             data[index2] = data[index1];
121             data[index1] = temp;
122         }
123     }
124 }

转载于:https://www.cnblogs.com/ywl925/archive/2013/01/22/2870474.html

堆排序-HeapSort相关推荐

  1. 排序算法笔记:堆排序 HeapSort in java

    2019独角兽企业重金招聘Python工程师标准>>> /*** 堆排序* 简述:* 首先使用建立最大堆的算法建立好最大堆,然后将堆顶元素(最大值)与最后一个值交换,同时使得堆的长度 ...

  2. java heapsort_排序算法笔记:堆排序 HeapSort in java

    /** * 堆排序 * 简述: * 首先使用建立最大堆的算法建立好最大堆,然后将堆顶元素(最大值)与最后一个值交换,同时使得堆的长度减小1 ,调用保持最大堆性质的算法调整,使得堆顶元素成为最大值,此时 ...

  3. 堆排序——HeapSort

    基本思想: 图示: (88,85,83,73,72,60,57,48,42,6) 平均时间复杂度: O(NlogN)由于每次重新恢复堆的时间复杂度为O(logN),共N - 1次重新恢复堆操作,再加上 ...

  4. 建堆 java_堆排序就这么简单

    一.堆排序介绍 来源百度百科: 堆排序(Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种.可以利用数组的特点快速定位指定索引的元素.堆分为大根堆和小根堆,是完 ...

  5. 上标3下标6算法_图解堆排序算法

    堆排序定义 一般来说,算法就像数学公式,前人经过不断优化和验证得到有规律性的公式留给后人使用,当然也会交给后人验证的思路.那么堆排序算法就是这样,它有基本固定的定义如下: 1.将数组构建为一颗有规则的 ...

  6. python3堆排序_python 堆排序

    堆排序 堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法.堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点(但是不保证所有左 ...

  7. 算法导论学习笔记 第6章 堆排序

    在本章中介绍了另一种排序算法:堆排序(heapsort).与归排序一样,但不同于插入排序的是,堆排序的时间复杂度式(Onlgn).而与插入排序相同,但不同于归并排序的是,堆排序同样具有空间原址性(我理 ...

  8. 【GIF动画+完整可运行源代码】C++实现 堆排序——十大经典排序算法之七

    十大经典排序算法系列博客-->传送门 堆排序Heapsort是指利用堆这种数据结构所设计的一种排序算法.堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大 ...

  9. 二叉排序树与文件操作的设计与实现_堆排序就这么简单

    一.堆排序介绍 来源百度百科: 堆排序(Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种.可以利用数组的特点快速定位指定索引的元素.堆分为大根堆和小根堆,是完 ...

最新文章

  1. 一文看尽目标检测:从YOLO v1到v3的进化之路
  2. 自查自纠 | 线性回归,你真的掌握了嘛?
  3. 成功解决TypeError: tuple indices must be integers or slices, not str
  4. 微信小程序引入WeUI
  5. WildFly 8与GlassFish 4 –选择哪个应用服务器
  6. 一文掌握深度学习、神经网络和学习过程的历史
  7. oracle用户密码复杂度查询,11gR2 Database用户密码复杂度验证
  8. linux mysql 6.0.4 启动_MySQL Connector/J 6.x jdbc.properties 配置, mysql-connector-java-6.0.4.jar 异常...
  9. LSTM背后的数学原理
  10. 解决Mac网络连接问题的一些方法
  11. linux删除一个网口的ip地址,linux一个网口多个ip地址
  12. ISIS协议与Quagga ISIS配置
  13. 十大常用经典排序算法总结!!!
  14. 制作背景为透明的图标
  15. FPGA是什么呢,通透讲解单片机和FPGA的区别
  16. [生存志] 第101节 九歌道尽楚芳华
  17. 【AI核心技术】课程二十五:机器也可以写诗——中文诗歌生成网络初探
  18. 小米8 android9手势,数码教程资讯:小米9怎么开启全面屏手势
  19. C#中base关键字的详解
  20. Vim查找替换操作 --- 查找和替换

热门文章

  1. 利用深度学习模型预测双色球
  2. 计算机网络:常考名词解释
  3. c语言localtime_s用法,localtime、localtime_s、localtime_r的使用
  4. clrscr()及gotoxy()函数
  5. 那些治愈者会再一次感染新冠病毒吗?
  6. 华赛(HuaSy)[华为(HuaWei)赛门铁克(Symantec)]与华为关系
  7. 比尔·盖茨:AI时代已经开启,GPT是40年来最具革命性技术
  8. 基于PaddleHub的圣诞节祝福语
  9. 域泛化(Domain Generalization)相关知识学习
  10. Android Studio 使用SQLite数据库来创建数据库+创建数据库表+更新表再次往表添加字段