一道排序选择题的解析以及构造最小堆

题目:对于给定的一组关键字(12,2,16,30,8,28,4,10,20,6,18),按照下列算法进行递增排序,写出每种算法第一趟排序后的结果:
希尔排序(增量为5)得到(1),快速排序(选择第一个记录为基准元素)得到(2),二路归并排序得到(3),堆排序得到(4)。

答案:

(1)12,2,10,20,6,18,4,16,30,8,28
(2)6,2,10,4,8,12,28,30,20,16,18
(3)2,12,16,30,8,28,4,10,6,20,18
(4)2,6,4,10,8,28,16,30,20,12,18

解析:

(1)希尔排序:
  • 先了解定义

希尔排序是插入排序的改进版,我们理解一个叫做下标差的的东西,也就是下面那个图中的增量d初始下标差为arr.length/2然后继续/2,对在同一下标差(相当于把这几个数单独拿出来了)的若干个数进行插入排序即可。

  • 过程
    12,2,16,30,8,28,4,10,20,6,18
    先是数组长度为11,那么d=11/2向下取整为5,而题目已经给出增量为5,可以不用计算。
对应下标012345678910
元素122163082841020618

利用下标0+5 = 5, 1+5=6。。。以此类推,进行分组,所以下表0与5一组,1与6一组。。。(同颜色为一组,最后剩下的不成双的就下标减去增量得到,如本次的18与28)
1221630,8,2841020,6,18

对各组进行大小的比较,大的放在右边,小的放在左边
1221020,6,1841630,8,28
第一轮结束,第二轮则是对d继续➗2操作,继续进行比较和交换,差不多这里也不写了。

(2)快速排序:

  • 先了解定义

快速排序就是每次找一个基点(第一个元素),然后两个哨兵,一个从最前面往后走,一个从最后面往前面走,如果后面那个哨兵找到了一个比基点的数下来,前面那个哨兵找到比基点的数下来,然后进行填坑,如果找不到最后两个哨兵就会碰到一起就结束,最后交换基点和哨兵相遇的地方的元素,然后就将一个序列分为比基点小的一部分和比基点大的一部分,然后递归左半部分和右半部分,最后的结果就是有序的了。

  • 本题选第一个为基准,即12,那么我们在12挖坑。(蓝色的是后面的哨兵处,绿色的是前面的哨兵处,()为坑)
    ( 12 ),2,16,30,8,28,4,10,20,6,18
    18>12,而后面的哨兵是要找比12小的,所以继续
    ( 12 ),2,16,30,8,28,4,10,20,6,18
    6<12, 后面的哨兵停下,把6填入12的坑内
    ( 6 ),2,16,30,8,28,4,10,20,6,18
    12坑填满6变成了坑,前面的哨兵前进!!找比12大的数
    6,2,16,30,8,28,4,10,20,( 6 ),18
    6,2,16,30,8,28,4,10,20,( 6 ),18
    前面的找到了16>12,停下!后面的哨兵前进!寻找比12小的
    6,2,16,30,8,28,4,10,20,( 6 ),18
    6,2,16,30,8,28,4,10,20,( 6 ),18
    后面的也找到了10<12,停下!把前面的16填入6坑处
    6,2,( 16 ),30,8,28,4,10,20,16,18
    6坑满了,把10填入16坑处,10变为坑
    6,2,10,30,8,28,4,( 10 ),20,16,18
    前面哨兵继续前进!
    6,2,10,30,8,28,4,( 10 ),20,16,18
    前面找到了,后面的继续前进!
    6,2,10,30,8,28,4,( 10 ),20,16,18
    后面也找到了!进行类似上几次的填坑操作,30入10坑,4入30坑,4变为坑
    6,2,10,( 30 ),8,28,4,30,20,16,18
    6,2,10,4,8,28,( 4 ),30,20,16,18
    前面哨兵继续前进!
    6,2,10,4,8,28,( 4 ),30,20,16,18
    6,2,10,4,8,28( 4 ),30,20,16,18
    后面哨兵继续前进!
    6,2,10,4,8,( 28 ),28,30,20,16,18
    两个哨兵碰面,路上的敌人消灭并汇合完毕!28放入4坑
    把一开始的基准元素12放到28坑
    6,2,10,4,8,12,28,30,20,16,18
    第一轮迭代结束,若是第二轮则是依旧选择第一个6作为基准进行遍历,这里就不说啦。

(3)归并排序:

  • 定义:

该算法是采用分治法,把数组不断分割,直至成为单个元素,然后比较再合并(合并的过程就是两部分分别从头开始比较,取出最小或最大元素的放到新的区域内,继续取两部分中最大或最小的元素,直到这两部分合并完,最后所有的都合并完,最后形成完整的有序序列)

12,2,16,30,8,28,4,10,20,6,18

  • 过程:
    对数组进行分组,分成最小而且可以比较的小组,所以是两个一组(同颜色为一组)
    12,2,16,30,8,28,4,10,20,6,18
    组内进行比较,小的在左,大的在右。
    2,12,16,30,8,28,4,10,6,20,18
    第一趟结束!!第二趟的话,就是进行更大的分组,这里就变成了四个一组。后面分组继续*2变大,直到分组长度大于或等于原数组长。

(4)堆排序

  • 最小堆定义:

双亲结点的值比每一个孩子结点的值都要小,根结点值最小。
聪明如你,应该知道最大堆的定义吧。

12,2,16,30,8,28,4,10,20,6,18
最初构造的树
在这里插入图片描述
构造最小堆:
首先是看左下角30、10、20的那棵子树,
10<30所以,10和30调换
看8、6、18的那棵子树,
6<8所以,6和8调换
在这里插入图片描述
再看以2为根的子树2、10、6,2<6、2<10所以不需要调换
看以16为根的子树,需要调换16、4
在这里插入图片描述
然后看12、2、4的树,2和12调换
在这里插入图片描述
看到子树12、10、6此时,还不满足最小堆,而6<10,所以12和6调换
在这里插入图片描述
此时,12、8、18也还不满足最小堆,子节点比父节点小即此处8<12,所以8和12调换
在这里插入图片描述
这就是最小堆了!!完全满足子节点比父节点小。
所以此时的序列是(从根到左子、右子)
2、6、4、10、8、28、16、30、20、12、18
就是我们的答案啦!

以上是全部题解以及联系的知识点的解析,个人顺便记录一下最小堆的构造,还有熟悉排序算法。

定义参考链接:
经典十大排序算法

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值