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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

常见排序算法:希尔排序

發(fā)布時(shí)間:2025/3/20 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 常见排序算法:希尔排序 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

為什么80%的碼農(nóng)都做不了架構(gòu)師?>>> ??

希爾排序(Shell's sort)是一種非常“神奇”的排序算法。說它“神奇”,是因?yàn)闆]有任何人能清楚地說明它的性能到底能到什么情況。希爾排序因DL.Shell于1959年提出而得名。自從C. A. R. Hoare在1962年提出快速排序后,由于其更為簡單,一般采用快速排序。但是,不少數(shù)學(xué)家們還是孜孜不倦地尋找希爾排序的最佳復(fù)雜度。作為普通程序員,我們可以學(xué)習(xí)下希爾的思路。

順便說一句,在希爾排序出現(xiàn)之前,計(jì)算機(jī)界普遍存在“排序算法不可能突破O(n2)”的觀點(diǎn)。希爾排序的出現(xiàn)打破了這個(gè)魔咒,很快,快速排序等算法相繼問世。從這個(gè)意義上說,希爾排序帶領(lǐng)我們走向了一個(gè)新的時(shí)代。

?

算法概述/思路

希爾排序的提出,主要基于以下兩點(diǎn):

1.插入排序算法在數(shù)組基本有序的情況下,可以近似達(dá)到O(n)復(fù)雜度,效率極高。

2.但插入排序每次只能將數(shù)據(jù)移動一位,在數(shù)組較大且基本無序的情況下性能會迅速惡化。

?

基于此,我們可以使用一種分組的插入排序方法,具體做法是:(以一個(gè)16元素大小的數(shù)組為例)

1.選擇一個(gè)增量delta,該增量大于1,從數(shù)組中按此增量選擇出子數(shù)組進(jìn)行一次直接插入排序。例如,若選擇增量為5,則對下標(biāo)為0,5,10,15的元素進(jìn)行排序。

2.保留該增量delta并依次移動首個(gè)元素進(jìn)行直接插入排序,直到一輪完成。對于上面的例子,則依次對數(shù)組[1,6,11],[2,7,12],[3,8,13],[4,9,14]進(jìn)行排序。

3.減小增量,不斷重復(fù)上述過程,直到增量減小為1.顯然,最后一次為直接插入排序。

4.排序完成。

從上面可以看出,增量是不斷減小的,因此,希爾排序又被成為“縮小增量排序”。

下面是希爾排序的示意圖(圖片來自維基百科):

?http://upload.wikimedia.org/wikipedia/commons/d/d8/Sorting_shellsort_anim.gif


代碼實(shí)現(xiàn)

實(shí)現(xiàn)代碼1:

public?static?void?shellSort(int[]?arr){?int?temp;?for?(int?delta?=?arr.length/2;?delta>=1;?delta/=2){??????????????????????????????//對每個(gè)增量進(jìn)行一次排序?for?(int?i=delta;?i<arr.length;?i++){???????????????for?(int?j=i;?j>=delta?&&?arr[j]<arr[j-delta];?j-=delta){?//注意每個(gè)地方增量和差值都是delta?temp?=?arr[j-delta];?arr[j-delta]?=?arr[j];?arr[j]?=?temp;?}?}//loop?i?}//loop?delta? }

實(shí)現(xiàn)代碼2:

public?static?void?shellSort2(int[]?arr){?int?delta?=?1;?while?(delta?<?arr.length/3){//generate?delta?delta=delta*3+1;????//?<O(n^(3/2))?by?Knuth,1973>:?1,?4,?13,?40,?121,?...?}??????????int?temp;?for?(;?delta>=1;?delta/=3){?for?(int?i=delta;?i<arr.length;?i++){???????????????for?(int?j=i;?j>=delta?&&?arr[j]<arr[j-delta];?j-=delta){?temp?=?arr[j-delta];?arr[j-delta]?=?arr[j];?arr[j]?=?temp;?}?}//loop?i?}//loop?delta? }

算法性能/復(fù)雜度

希爾排序的增量數(shù)列可以任取,需要的唯一條件是最后一個(gè)一定為1(因?yàn)橐WC按1有序)。但是,不同的數(shù)列選取會對算法的性能造成極大的影響。上面的代碼演示了兩種增量。

切記:增量序列中每兩個(gè)元素最好不要出現(xiàn)1以外的公因子!(很顯然,按4有序的數(shù)列再去按2排序意義并不大)。

下面是一些常見的增量序列。

第一種增量是最初Donald Shell提出的增量,即折半降低直到1。據(jù)研究,使用希爾增量,其時(shí)間復(fù)雜度還是O(n2)。

第二種增量Hibbard:{1, 3, ..., 2^k-1}。該增量序列的時(shí)間復(fù)雜度大約是O(n^1.5)。

第三種增量Sedgewick增量:(1, 5, 19, 41, 109,...),其生成序列或者是9*4^i - 9*2^i + 1或者是4^i - 3*2^i + 1。

下面的表中有更多的增量(來自http://en.wikipedia.org/wiki/Shellsort):

算法穩(wěn)定性

我們都知道插入排序是穩(wěn)定算法。但是,Shell排序是一個(gè)多次插入的過程。在一次插入中我們能確保不移動相同元素的順序,但在多次的插入中,相同元素完全有可能在不同的插入輪次被移動,最后穩(wěn)定性被破壞,因此,Shell排序不是一個(gè)穩(wěn)定的算法。

?

算法適用場景

Shell排序雖然快,但是畢竟是插入排序,其數(shù)量級并沒有后起之秀--快速排序O(n㏒n)快。在大量數(shù)據(jù)面前,Shell排序不是一個(gè)好的算法。但是,中小型規(guī)模的數(shù)據(jù)完全可以使用它。


轉(zhuǎn)載于:https://my.oschina.net/lifj/blog/389714

總結(jié)

以上是生活随笔為你收集整理的常见排序算法:希尔排序的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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