日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

《大话数据结构》第9章 排序 9.6 希尔排序(下)

發(fā)布時間:2025/3/21 编程问答 13 豆豆
生活随笔 收集整理的這篇文章主要介紹了 《大话数据结构》第9章 排序 9.6 希尔排序(下) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

9.6.3?希爾排序算法

????????好了,為了能夠真正弄明白希爾排序的算法,我們還是老辦法——模擬計算機在執(zhí)行算法時的步驟還研究算法到底是如何進行排序的。
??????? 希爾排序算法代碼如下。

void ShellSort(SqList *L) {int i,j;int increment=L->length;do{increment=increment/3+1; /* 增量序列 */for(i=increment+1;i<=L->length;i++){if (L->r[i]<L->r[i-increment]) /* 需將L->r[i]插入有序增量子表 */ { L->r[0]=L->r[i]; /* 暫存在L->r[0] */for(j=i-increment;j>0 && L->r[0]<L->r[j];j-=increment)L->r[j+increment]=L->r[j]; /* 記錄后移,查找插入位置 */L->r[j+increment]=L->r[0]; /* 插入 */}}}while(increment>1); }

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)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。