希尔排序-Java
希爾排序的實(shí)質(zhì)就是分組插入排序,該方法又稱縮小增量排序,因DL.Shell于1959年提出而得名。
?
該方法的基本思想是:先將整個(gè)待排元素序列分割成若干個(gè)子序列(由相隔某個(gè)“增量”的元素組成的)分別進(jìn)行直接插入排序,然后依次縮減增量再進(jìn)行排序,待整個(gè)序列中的元素基本有序(增量足夠小)時(shí),再對(duì)全體元素進(jìn)行一次直接插入排序。因?yàn)橹苯硬迦肱判蛟谠鼗居行虻那闆r下(接近最好情況),效率是很高的,因此希爾排序在時(shí)間效率上比前兩種方法有較大提高。
?
以n=10的一個(gè)數(shù)組49, 38, 65, 97, 26, 13, 27, 49, 55, 4為例
第一次 gap = 10 / 2 = 5
49 ??38? ?65? ?97? ?26? ?13? ?27? ?49? ?55? ?4
1A?????????????????????? ???????????????? 1B
??????? 2A?????????????????????????????????????????2B
?????????????????3A?????????????????????????????????????????3B
???????????????????????? 4A??????????????????????????????????????????4B
????????????????????????????????? 5A?????????????????????????????????????????5B
1A,1B,2A,2B等為分組標(biāo)記,數(shù)字相同的表示在同一組,大寫字母表示是該組的第幾個(gè)元素, 每次對(duì)同一組的數(shù)據(jù)進(jìn)行直接插入排序。即分成了五組(49, 13) (38, 27) (65, 49)? (97, 55)? (26, 4)這樣每組排序后就變成了(13, 49)? (27, 38)? (49, 65)? (55, 97)? (4, 26),下同。
第二次 gap = 5 / 2 = 2
排序后
13? ?27? ?49? ?55? ?4?? ?49? ?38? ?65? ?97? ?26
1A????????? ???1B?????????? ??1C?????????? ???1D????????? ??1E
??????? 2A???????????????2B?????????? ??2C????????? ???2D?????????? ???2E
第三次 gap = 2 / 2 = 1
4?? 26?? 13?? 27?? 38??? 49?? 49?? 55?? 97?? 65
1A?? 1B?????1C????1D????1E??????1F?????1G????1H?????1I?????1J
第四次 gap = 1 / 2 = 0 排序完成得到數(shù)組:
4?? 13?? 26?? 27?? 38??? 49?? 49?? 55? ?65?? 97
?
下面給出嚴(yán)格按照定義來(lái)寫的希爾排序
[cpp]?view plaincopy很明顯,上面的shellsort1代碼雖然對(duì)直觀的理解希爾排序有幫助,但代碼量太大了,不夠簡(jiǎn)潔清晰。因此進(jìn)行下改進(jìn)和優(yōu)化,以第二次排序?yàn)槔?#xff0c;原來(lái)是每次從1A到1E,從2A到2E,可以改成從1B開始,先和1A比較,然后取2B與2A比較,再取1C與前面自己組內(nèi)的數(shù)據(jù)比較…….。這種每次從數(shù)組第gap個(gè)元素開始,每個(gè)元素與自己組內(nèi)的數(shù)據(jù)進(jìn)行直接插入排序顯然也是正確的。
[cpp]?view plaincopy
再將直接插入排序部分用?白話經(jīng)典算法系列之二 直接插入排序的三種實(shí)現(xiàn)??中直接插入排序的第三種方法來(lái)改寫下:
這樣代碼就變得非常簡(jiǎn)潔了。
??
附注:上面希爾排序的步長(zhǎng)選擇都是從n/2開始,每次再減半,直到最后為1。其實(shí)也可以有另外的更高效的步長(zhǎng)選擇,如果讀者有興趣了解,請(qǐng)參閱維基百科上對(duì)希爾排序步長(zhǎng)的說(shuō)明:
http://zh.wikipedia.org/wiki/%E5%B8%8C%E5%B0%94%E6%8E%92%E5%BA%8F
總結(jié)
- 上一篇: Java静态内部类
- 下一篇: 希尔排序-Java二