本文从以下几个方面阐述堆排序:
1 何谓“堆”?
2 完全二叉树的特点
3 堆排序如何实现?
4 树的存储
5 PriorityQueue内部如何实现堆排序?
6 总结。
1 何谓“堆”?
一个序列满足以下定义,我们把它称作“堆”:
a)以完全二叉树的结构存储 ;b)所有非终端节点的值均不大于或者不小于其左右孩子节点的值。
注意:此处用的是“不大于或者不小于”,说明节点等于它的左或右孩子也是可以的。“不大于”时为小顶堆,“不小于”时为大顶堆。
如图:
注意:大顶堆的堆顶元素并不一定是最大的。只要满足了上述情况即可以成为“堆”。要使堆顶元素最大或者最小,则需要用到堆排序,完成的就是每次得到最大(或者最小)堆顶元素并输出得到有序序列的过程。
2 完全二叉树
从上面对“堆”的定义可知:堆首先是一棵完全二叉树,那么在分析堆排序之前我们有必要先来了解以下什么是完全二叉树:
定义:深度为k,有n个节点的二叉树,当且仅当其每一个节点都与深度为k的满二叉树中编号从1~n的节点一一对应,这样的树称为完全二叉树。(此处不详谈,对此不理解的读者请自己百度之)
完全二叉树的特点:
1)叶子节点只可能在层次最大的两层上出现。
2)当右分支下的子的最大层次为L时,左分支下的子孙的最大层必为L或者L+1。
完全二叉树的性质:
1)具有n个节点的完全二叉树的深度为[logN]+1.
2) 节点从1~n,若节点i>1,则双亲是节点[i/2](取整);若2i>n,则无左孩子,否则左孩子为2i;若2i+1>n,则无右孩子,否则右孩子为2i+1.
3 堆排序如何实现?
步骤:a)初始建堆:即由一个无序序列建立一个堆。b)筛选重新建堆,保证每次得到的堆顶元素为最大或者最小,输出堆顶元素,重复操作,得到有序序列。
首先我们来看如何筛选建堆?假设现在已经有一个建立好的小顶堆,输出堆顶元素后,我们如何把剩余的元素重新建一个堆,使得堆顶元素最小呢?
看图:
方法如下:输出13后,把最后一个元素80换到堆顶位置,因为80>27,则又需交换27与80的位置,又发现80>65,因此又需交换80与65的位置,最后得到:
此即为输出13之后对剩余元素的重新筛选建立堆。
现在再让我们回到前面,我们如何从一个无序序列得到初始的小顶堆呢?其实初始建堆就是把上述过程反复的执行。首先把无序序列构造为一棵完全二叉树,从下往上比较每一个节点与其双亲节点,小的值上移,如此遍历完整棵树,则得到了一个初始的小顶堆。
注:笔者表达能力有限,对此不清楚的读者请翻看数据结构书......
4 树的存储。
了解了堆排序的原理后,这样的过程如何在代码中实现呢?我们先得知道树的存储结构:
1)双亲表示法。即数组存储。用一组连续的空间存放树的节点,每个节点中设一个指示器指向双亲节点在数组中的位置。
优劣:找双亲容易,但要找某一个节点的儿子则需要遍历整个数组。
2)孩子表示法:即数组与链表结合存储。每个节点放在顺序存储的结构中,每个节点中又包括一个指向其孩子的指针。大概形式如下图:
3)孩子兄弟表示法:即链表存储。(此处详情略)
5 PriorityQueue内部如何实现堆排序:
此处在我的另外一篇博客http://792881908-qq-com.iteye.com/blog/1454401 中有解析。
6 总结:
堆排序是一种在树形选择排序上的优化,有它一定的优势,但在记录较少的文件中并不提倡,对于它和其他排序方式性能的比较还有待进一步分析。
- 大小: 25.6 KB
- 大小: 25.4 KB
- 大小: 53.8 KB
- 大小: 41.5 KB
分享到:
相关推荐
总结来说,堆排序是一种利用堆数据结构进行排序的有效方法,它包括了建堆和调整堆两个关键步骤。在C++中,堆排序可以通过自定义函数实现,如`heapify()`、`buildHeap()`和`heapSort()`。理解并实践这些函数的编写,...
数据结构排序 堆排序 堆排序是一种常用的排序算法,它使用大堆进行排序。下面是堆排序的详细知识点说明: 堆排序定义 堆排序是一种比较排序算法,它使用大堆(max heap)来对数组进行排序。堆排序的时间复杂度为O...
Java 数据结构之堆排序(HeapSort)详解及实例 堆排序是一种常用的排序算法,它将数组分为大根堆和小根堆,并利用堆的性质对数组进行排序。在 Java 中,堆排序可以通过构建最大堆、选择堆顶元素、交换堆顶元素与第 ...
堆排序是一种基于比较的排序算法,它利用了数据结构中的“堆”这一概念。在数据结构中,堆通常被理解为一个完全二叉树,它满足堆的性质:父节点的值要么大于或等于其子节点(大顶堆),要么小于或等于其子节点(小...
数据结构习题堆排序程序,将每行代码前的注释去掉即可运行
### 数据结构课程设计实验报告——堆排序 #### 一、堆排序概述 堆排序是一种基于树形选择的排序算法,其核心在于利用完全二叉树的性质进行元素的选择与排序。在排序过程中,将待排序的数据集合视为一颗完全二叉树...
数据结构——堆排序 数据结构——堆排序 数据结构——堆排序 数据结构——堆排序 数据结构——堆排序 数据结构——堆排序
"C语言学习之排序数据结构链表堆排序希尔排序快速排序递归排序" 本资源主要介绍了C语言中的排序算法,包括链表、堆排序、希尔排序、快速排序和递归排序等五种方法。同时,文章还提供了每种排序方法的原理、流程图和...
数据结构实验,顺序表单链表的基本操作,堆排序等到等
堆排序是一种基于比较的排序算法,它利用了二叉堆(通常为最大堆)的数据结构来完成排序过程。堆排序可以分为两个阶段:构建最大堆与交换堆顶元素并重新调整堆。 - **构建最大堆**:初始时将待排序数组构建成一个...
本文实例为大家分享了C语言堆排序源代码,供大家参考,具体内容如下 1. 堆排序 堆排序的定义及思想可以参考百度百科: 用一句概括,堆排序就是一种改进的选择排序,改进的地方在于,每次做选择的时候,不单单把最大...
按照算法导论上的伪代码写出的堆数据结构,实现的是最大堆的堆排序
首先,堆排序是一种基于比较的排序算法,利用了二叉堆的数据结构。二叉堆是一个完全二叉树,可以分为最大堆或最小堆,其中每个父节点的值都大于或等于其子节点。堆排序的过程包括构建初始堆和调整堆。首先,将无序...
数据结构堆排序的java算法实现,里面用java语言实现了堆排序的算法实现,有输入和输出结果
用函数实现堆排序,并输出每趟排序的结果 Input 第一行:键盘输入待排序关键的个数n 第二行:输入n个待排序关键字,用空格分隔数据 Output 第一行:初始建堆后的结果 其后各行输出交换堆顶元素并调整堆的结果,数据...
用C++实现堆排序的源程序,运用数据结构中的堆排序写成的代码,可以在做数据结构课程设计的时候用到
使用C语言编写的数据结构程序,为堆排序算法的实现。可作为课程设计题目来做。
严蔚敏教授的《数据结构》一书是学习数据结构的经典教材,其中对堆排序有详细的介绍和伪码描述。 1. 堆的定义与性质: - 完全二叉树:在堆中,数据元素按照完全二叉树的形式存储,也就是说除了最后一层外,每一层...