Java实现的几个常用排序算法详细解读-2
上一篇 / 下一篇 2012-06-29 13:41:06 / 个人分类:Java
lr&G$Vk&I.|;|*l.al0 希尔排序的诞生是由于插入排序在处理大规模数组的时候会遇到需要移动太多元素的问题。希尔排序的思想是将一个大的数组“分而治之”,划分为若干 个小的数组,以 gap 来划分,比如数组 [1, 2, 3, 4, 5, 6, 7, 8] ,如果以 gap = 2 来划分,可以分为 [1, 3, 5, 7] 和 [2, 4, 6, 8] 两个数组(对应的,如 gap = 3 ,则划分的数组为: [1, 4, 7] 、 [2, 5, 8] 、 [3, 6] )然后分别对划分出来的数组进行插入排序,待各个子数组排序完毕之后再减小 gap 值重复进行之前的步骤,直至 gap = 1 ,即对整个数组进行插入排序,此时的数组已经基本上快排好序了,所以需要移动的元素会很小很小,解决了插入排序在处理大规模数组时较多移动次数的问题。51Testing软件测试网]-xo a,R1[E1u&x1k
51Testing软件测试网+X+]Y,c6m5e(P H具体实例请参照插入排序。
io-nkPV \ D `&g0/WQ)I4J],X0 希尔排序是插入排序的改进版,在数据量大的时候对效率的提升帮助很大,数据量小的时候建议直接使用插入排序就好了。51Testing软件测试网n-Q/}0} SB&U
51Testing软件测试网J-sTq)v&Sd)R实现代码:
tB4o O*i y0b$TX(g!w&qB{0 51Testing软件测试网(ub/Gc,z5[ \
|
#k Y H.Wm*Nn0 5、归并排序51Testing软件测试网T `-I C/|;N5j{
x v#e0z(Qg2L]0 归并排序采用的是递归来实现,属于“分而治之”,将目标数组从中间一分为二,之后分别对这两个数组进行排序,排序完毕之后再将排好序的两个数组 “归并”到一起,归并排序最重要的也就是这个“归并”的过程,归并的过程中需要额外的跟需要归并的两个数组长度一致的空间,比如需要规定的数组分别为: [3, 6, 8, 11] 和 [1, 3, 12, 15] (虽然逻辑上被划为为两个数组,但实际上这些元素还是位于原来数组中的,只是通过一些 index 将其划分成两个数组,原数组为 [3, 6, 8, 11, 1, 3, 12, 15 ,我们设置三个指针 lo, mid, high 分别为 0,3,7 就可以实现逻辑上的子数组划分)那么需要的额外数组的长度为 4 + 4 = 8 。归并的过程可以简要地概括为如下:
'ne,{E`0 51Testing软件测试网!o!?H.EIe(L1)将两个子数组中的元素复制到新数组 copiedArray 中,以前面提到的例子为例,则 copiedArray = [3, 6, 8, 11, 1, 3, 12, 15] ;51Testing软件测试网 w'_N-F!yw
51Testing软件测试网!g1er_4}.g5Euo M2)设置两个指针分别指向原子数组中对应的第一个元素,假定这两个指针取名为 leftIdx 和 rightIdx ,则 leftIdx = 0 (对应 copiedArray 中的第一个元素 [3] ), rightIdx = 4 (对应 copiedArray 中的第五个元素 [1] );51Testing软件测试网C5oB P X
51Testing软件测试网,p)A6b6r;u3)比较 leftIdx 和 rightIdx 指向的数组元素值,选取其中较小的一个并将其值赋给原数组中对应的位置 i ,赋值完毕后分别对参与赋值的这两个索引做自增 1 操作,如果 leftIdx 或 rigthIdx 值已经达到对应数组的末尾,则余下只需要将剩下数组的元素按顺序 copy 到余下的位置即可。51Testing软件测试网4p|NU"xA
51Testing软件测试网5cJ'XL bI下面给个归并的具体实例:51Testing软件测试网"E*qg5I"Wxv-t
9F2@9Q2OqL0 51Testing软件测试网8Zh sdZ/B
|
#c/} ^*KH0s1^%CF0 以上便是一次归并的过程,我们可以将整个需要排序的数组做有限次拆分(每次一分为二)直到分为长度为 1 的小数组为止,长度为 1 时数组已经不用排序了。在这之后再逆序(由于采用递归)依次对这些数组进行归并操作,直到最后一次归并长度为 n / 2 的子数组,归并完成之后数组排序也完成。
9l$W dhA_"P\04C h Wve'm9me h0 归并排序需要的额外空间是所有排序中最多的,每次归并需要与参与归并的两个数组长度之和相同个元素(为了提供辅助数组)。则可以推断归并排序的 空间复杂度为 1 + 2 + 4 + … + n = n * ( n + 2) / 4 (忽略了 n 的奇偶性的判断),时间复杂度比较难估,这里小弟也忘记是多少了(囧)。51Testing软件测试网LTe[%j0Qg!X
2z9o:AB(s rz}1Ot0 实现代码:51Testing软件测试网&X AV8j8yeu(EE6r.z
A O wd4_&_ z0
Vm+Gj7n8QZ}0
|
6、快速排序51Testing软件测试网7];Ta)n9FGO1y%W
51Testing软件测试网ai%g+?!}?Ng快速排序也是用归并方法实现的一个“分而治之”的排序算法,它的魅力之处在于它能在每次 partition (排序算法的核心所在)都能为一个数组元素确定其排序最终正确位置(一次就定位准,下次循环就不考虑这个元素了)。51Testing软件测试网!gfhbR
TAG:
不要让那些真正对你好的人,慢慢的从你的生活中消失,无论爱情还是友情,都需要用心经营。
我的栏目
标题搜索
日历
|
|||||||||
日 | 一 | 二 | 三 | 四 | 五 | 六 | |||
1 | 2 | 3 | 4 | 5 | 6 | ||||
7 | 8 | 9 | 10 | 11 | 12 | 13 | |||
14 | 15 | 16 | 17 | 18 | 19 | 20 | |||
21 | 22 | 23 | 24 | 25 | 26 | 27 | |||
28 | 29 | 30 |
我的存档
数据统计
- 访问量: 3338558
- 日志数: 1640
- 建立时间: 2011-12-07
- 更新时间: 2019-12-24