您的位置:首页 > 编程语言 > C语言/C++

图解排序算法及C语言实现之 ------ 堆排序:Heap Sort

2014-01-14 14:01 501 查看
一、定义及算法原理
1. 什么叫堆排序?

顾名思义,就是利用堆的结构进行排序的一种算法。那么什么叫堆呢?其实堆是一个二叉树,它首先是一个完全二叉树,并且,非叶子节点不小于左右孩子节点的值或者不大于左右孩子节点的值,不小于左右孩子的叫大顶堆,反之称为小顶堆。我们按大顶堆的情况来分析堆排序的过程,小顶堆情况类似。

2.基本算法原理

从最后一个非叶子节点开始构造一个大顶堆,然后把根节点与最后一个元素交换,这是最后一个元素就是堆中的最大值,继续利用除最后一个元素外的节点重新构造大顶堆。继续交换根节点与最后一个元素,重复进行,直到所有节点交换完毕,便生成一个排序好的数列。

3. 图形表示,从最后一个非叶子节点开始构造大顶堆 ,您看明白了吗?



二、图解排序实现过程:
第一遍

从第一给非叶子节点,即紫色圈圈标号为3的节点开始,构造大顶堆。

首先用3号节点与它的左右叶子节点3个元素构造一个大顶堆。

先把父节点的值放在一个临时地方,假设是一个box,如下图的蓝色方框,然后设置当前位置pos指向3号节点,如红色箭头,这时box=10, pos=3,再比较左右节点的大小,用大的跟父节点比较,左节点80大,所以把80放在父节点的位置,接着pos移到左节点的位置,即pos=7,最后把box里面的值10赋给左节点。结束一个节点的构造,接着继续从上一个非叶子节点构造大顶堆,如图二。

图一



用2号节点与它的左右叶子节点3个元素构造一个大顶堆。

先把值11放在box里面,box=11, 当前位置是1,pos=1。然后比较左右节点的大小,用值大的右节点跟父节点比较,15大于11,所以右节点的15放到父节点位置,box里面的值赋给右节点,位置变量pos=6。下一步用1号节点当根节点构造大顶堆。

图二



1号节点当父节点构造大顶堆。



从根节点开始构造大顶堆。



第一遍结束后已经生成一个完整的大顶堆。下一遍先用根节点与最后一个叶子节点交换,根节点放在最后为最大值,除这个节点外的所有节点重新生成大顶堆。

第二遍

第二遍开始,先用根节点跟最后一个节点交换,即根节点值为5,最后一个节点的值为80,接着用除80节点外的所有节点重新生成大顶堆。



第三遍,重复第二遍的过程,根节点50放在倒数第二个叶子节点的位置,是第二大的元素,剩下的节点重新生成大顶堆。过程不再重复画图。

三、程序实现步骤图

紫色圈圈是排序的步骤

1. 从最后一个非叶子节点开是构造大顶堆,如下图一为最后一个非叶子节点为父节点构造大顶堆的过程。紫色圈圈表示处理的步骤,第一步,先把父节点的值放到一个临时地方,第二步比较2个子节点的大小,第三步用大的值跟临时值比较,如果比临时值大,则值放到父节点的位置。第四步记下当前最大值子节点的位置,第五步,如果该节点没有子节点,则把临时变量的值放到该位置,如果该节点有子节点,如图二,则以它为父节点,重新构造这颗子树的大顶堆。

2. 交换根节点与最后一个叶子节点的值,如图三。

3. 按1方法重新构造出最后一个节点外的所有节点的大顶堆。

图一 图二 图三



四、C语言代码实现

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: