答案:题目:对于给定的一组关键字(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,可以不用计算。
对应下标 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|---|
元素 | 12 | 2 | 16 | 30 | 8 | 28 | 4 | 10 | 20 | 6 | 18 |
利用下标0+5 = 5, 1+5=6。。。以此类推,进行分组,所以下表0与5一组,1与6一组。。。(同颜色为一组,最后剩下的不成双的就下标减去增量得到,如本次的18与28)
12,2,16,30,8,28,4,10,20,6,18
对各组进行大小的比较,大的放在右边,小的放在左边
12,2,10,20,6,18,4,16,30,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
就是我们的答案啦!
以上是全部题解以及联系的知识点的解析,个人顺便记录一下最小堆的构造,还有熟悉排序算法。
定义参考链接:
经典十大排序算法