`
微Smile
  • 浏览: 34857 次
  • 性别: Icon_minigender_2
  • 来自: 湖南
社区版块
存档分类
最新评论

【数据结构】之堆排序

 
阅读更多

本文从以下几个方面阐述堆排序:

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 数据结构之堆排序(HeapSort)详解及实例 堆排序是一种常用的排序算法,它将数组分为大根堆和小根堆,并利用堆的性质对数组进行排序。在 Java 中,堆排序可以通过构建最大堆、选择堆顶元素、交换堆顶元素与第 ...

    数据结构—堆排序

    堆排序是一种基于比较的排序算法,它利用了数据结构中的“堆”这一概念。在数据结构中,堆通常被理解为一个完全二叉树,它满足堆的性质:父节点的值要么大于或等于其子节点(大顶堆),要么小于或等于其子节点(小...

    数据结构习题堆排序程序

    数据结构习题堆排序程序,将每行代码前的注释去掉即可运行

    数据结构课程设计 实验报告——堆排序

    ### 数据结构课程设计实验报告——堆排序 #### 一、堆排序概述 堆排序是一种基于树形选择的排序算法,其核心在于利用完全二叉树的性质进行元素的选择与排序。在排序过程中,将待排序的数据集合视为一颗完全二叉树...

    数据结构——堆排序.h

    数据结构——堆排序 数据结构——堆排序 数据结构——堆排序 数据结构——堆排序 数据结构——堆排序 数据结构——堆排序

    c语言学习之排序 数据结构 链表 堆排序 希尔排序 快速排序 递归排序

    "C语言学习之排序数据结构链表堆排序希尔排序快速排序递归排序" 本资源主要介绍了C语言中的排序算法,包括链表、堆排序、希尔排序、快速排序和递归排序等五种方法。同时,文章还提供了每种排序方法的原理、流程图和...

    数据结构实验堆排序详细源程序

    数据结构实验,顺序表单链表的基本操作,堆排序等到等

    堆排序 数据结构 C语言

    堆排序是一种基于比较的排序算法,它利用了二叉堆(通常为最大堆)的数据结构来完成排序过程。堆排序可以分为两个阶段:构建最大堆与交换堆顶元素并重新调整堆。 - **构建最大堆**:初始时将待排序数组构建成一个...

    C语言数据结构之堆排序源代码

    本文实例为大家分享了C语言堆排序源代码,供大家参考,具体内容如下 1. 堆排序 堆排序的定义及思想可以参考百度百科: 用一句概括,堆排序就是一种改进的选择排序,改进的地方在于,每次做选择的时候,不单单把最大...

    C语言实现的堆数据结构及堆排序

    按照算法导论上的伪代码写出的堆数据结构,实现的是最大堆的堆排序

    数据结构堆排序 快速排序 归并排序

    首先,堆排序是一种基于比较的排序算法,利用了二叉堆的数据结构。二叉堆是一个完全二叉树,可以分为最大堆或最小堆,其中每个父节点的值都大于或等于其子节点。堆排序的过程包括构建初始堆和调整堆。首先,将无序...

    数据结构堆排序的java算法实现

    数据结构堆排序的java算法实现,里面用java语言实现了堆排序的算法实现,有输入和输出结果

    数据结构 堆排序 输出每一趟结果

    用函数实现堆排序,并输出每趟排序的结果 Input 第一行:键盘输入待排序关键的个数n 第二行:输入n个待排序关键字,用空格分隔数据 Output 第一行:初始建堆后的结果 其后各行输出交换堆顶元素并调整堆的结果,数据...

    数据结构课程设计堆排序的C++实现

    用C++实现堆排序的源程序,运用数据结构中的堆排序写成的代码,可以在做数据结构课程设计的时候用到

    C语言数据结构堆排序算法

    使用C语言编写的数据结构程序,为堆排序算法的实现。可作为课程设计题目来做。

    堆排序算法(严蔚敏数据结构)

    严蔚敏教授的《数据结构》一书是学习数据结构的经典教材,其中对堆排序有详细的介绍和伪码描述。 1. 堆的定义与性质: - 完全二叉树:在堆中,数据元素按照完全二叉树的形式存储,也就是说除了最后一层外,每一层...

Global site tag (gtag.js) - Google Analytics