《大话数据结构》第9章 排序 9.6 希尔排序(下)
9.6.3?希爾排序算法
????????好了,為了能夠真正弄明白希爾排序的算法,我們還是老辦法——模擬計算機在執(zhí)行算法時的步驟還研究算法到底是如何進行排序的。
??????? 希爾排序算法代碼如下。
1)?程序開始運行,此時我們傳入的SqList參數(shù)的值為length=9,r[10]={0,9,1,5,8,3,7,4,6,2}。這就是我們需要等待排序的序列,如圖9-6-4所示。
2)?第4行,變量increment就是那個“增量”,我們初始值讓它等于待排序的記錄數(shù)。
3)?第5~19行是一個do循環(huán),它提終止條件是increment不大于1時。其實也就是增量為1時就停止循環(huán)了。
4)?第7行,這一句很關(guān)鍵,但也是難以理解的地方,我們后面還要談到它,先放一放。這里執(zhí)行完成后,increment=9/3+1=4。
5)?第8~17行是一for循環(huán),i從4+1=5開始到9結(jié)束。
6)?第10行,判斷L.r[i]與L.r[i-increment]大小,L.r[5]=3<L.r[i-increment]=L.r[1]=9,滿足條件,第12行,將L.r[5]=3暫存入L.r[0]。第13~14行的循環(huán)只是為了將L.r[1]=9的值賦給L.r[5],由于循環(huán)的增量是j-=increment,其實它就循環(huán)了一次,此時j=-3。第15行,再將L.r[0]=3賦值給L.r[j+increment]=L.r[-3+4]=L.r[1]=3。如圖9-6-5,事實上,這一段代碼就干了一件事,就是將第5位的3和第1位的9交換了位置。
7)?循環(huán)繼續(xù),i=6,L.r[6]=7>L.r[i-increment]=L.r[2]=1,因此不交換兩者數(shù)據(jù)。如圖9-6-6。
?
8)?循環(huán)繼續(xù),i=7,L.r[7]=4<L.r[i-increment]=L.r[3]=5,交換兩者數(shù)據(jù)。如圖9-6-7。
9)?循環(huán)繼續(xù),i=8,L.r[8]=6<L.r[i-increment]=L.r[4]=8,交換兩者數(shù)據(jù)。如圖9-6-8。
10)?循環(huán)繼續(xù),i=9,L.r[9]=2<L.r[i-increment]=L.r[5]=9,交換兩者數(shù)據(jù)。注意,第13~14行是循環(huán),此時還要繼續(xù)比較L.r[5]與L.r[1]的大小,因為2<3,所以還要交換L.r[5]與L.r[1]的數(shù)據(jù),如圖9-6-9。
??????? 最終第一輪循環(huán)后,數(shù)組的排序結(jié)果為圖9-6-10所示。細心的同學(xué)會發(fā)現(xiàn),我們的數(shù)字1、2等小數(shù)字已經(jīng)在前兩位,而8、9等大數(shù)字已經(jīng)在后兩位,也就是說,通過這樣的排序,我們已經(jīng)讓整個序列基本有序了。這其實就是希爾排序的精華所在,它將關(guān)鍵字較小的記錄,不是一步一步地往前挪動,而是跳躍式地往前移,從而使得每次完成一輪循環(huán)后,整個序列就朝著有序堅實地邁進一步。
?
11)?我們繼續(xù),在完成一輪do循環(huán)后,此時由于increment=4>1因此我們需要繼續(xù)do循環(huán)。第7行得到increment=4/3+1=2。第8~17行for循環(huán),i從2+1=3開始到9結(jié)束。當(dāng)i=3、4時,不用交換,當(dāng)i=5時,需要交換數(shù)據(jù),如圖9-6-11
12)?此后,i=6、7、8、9均不用交換。如圖9-6-12
13)?再次完成一輪do循環(huán),increment=2>1,再次do循環(huán),第7行得到increment=2/3+1=1。此時這就是最后一輪do循環(huán)了。盡管第8~17行for循環(huán),i從1+1=2開始到9結(jié)束,但由于當(dāng)前序列已經(jīng)基本有序,可交換數(shù)據(jù)的情況大為減少,效率其實很高。如圖9-6-13,圖中箭頭連線為需要交換的關(guān)鍵字。
?
最終完成排序過程,如圖9-6-14。
?
9.6.4?希爾排序復(fù)雜度分析
??????? 通過這段代碼的剖析,相信大家有些明白,希爾排序的關(guān)鍵并不是隨便的分組后各自排序,而是將相隔某個“增量”的記錄組成一個子序列,實現(xiàn)跳躍式的移動,使得排序的效率提高。
??????? 這里“增量”的選取就非常關(guān)鍵了。我們在代碼中第7行,是用increment=increment/3+1;的方式選取增量的,可究竟應(yīng)該選取什么樣的增量才是最好,目前還是一個數(shù)學(xué)難題,迄今為止還沒有人找到一種最好的增量序列。不過大量的研究表明,當(dāng)增量序列為dlta[k]=2t-k+1-1(0≤k≤t≤?log2(n+1)?)時,可以獲得不錯的效率,其時間復(fù)雜度為O(n3/2),要好于直接排序的O(n2)。需要注意的是,增量序列的最后一個增量值必須等于1才行。另外由于記錄是跳躍式的移動,希爾排序并不是一種穩(wěn)定的排序算法。
??????? 不管怎么說,希爾排序算法的發(fā)明,使得我們終于突破了慢速排序的時代(超越了時間復(fù)雜度為O(n2)),之后,相應(yīng)的更為高效的排序算法也就相繼出現(xiàn)了。
出處:http://www.cnblogs.com/cj723/archive/2011/04/20/2021648.html
總結(jié)
以上是生活随笔為你收集整理的《大话数据结构》第9章 排序 9.6 希尔排序(下)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《大话数据结构》第9章 排序 9.6 希
- 下一篇: 《大话数据结构》第9章 排序 9.7 堆