希爾排序 shell sort

希爾排序

  • 時(shí)間復(fù)雜度:平均O(n^1.3),最好為O(n),最壞為0(n ^ 2)
  • 空間復(fù)雜度:O(1)
  • 穩(wěn)定性:不穩(wěn)定

算法解析:

  • 希爾排序是直接插入排序的一種改進(jìn),又稱做縮小增量排序
  • 希爾排序是把待排序集合計(jì)算出一個(gè)增量集合Tn
  • 把待排序集合分成若干個(gè)子集,然后每個(gè)子集進(jìn)行直接插入排序剥险,知道Ti=1為止,排序結(jié)束
  • 遍歷次數(shù)為增量集合的count數(shù)

舉例

有一個(gè)集合如下圖所示:


list.png

計(jì)算增量:gap = length/2

  • 第一次:gap = 4蟀俊,把待排序列劃分為4個(gè)子序列


    第一次.png
  • 第二次 :gap = 2旗扑,把待排序列劃分為2個(gè)子序列


    第二次.png
  • 第三次:gap = 1捎谨,進(jìn)行一次直接插入排序诫尽,排序結(jié)束

排序結(jié)果:
第一次:7 3 1 2 8 5 4 10 9
第二次:1 2 4 3 7 5 8 10 9
第三次:1 2 3 4 5 7 8 9 10

C語言實(shí)現(xiàn)

void shellSort(int arr[],int length) {
     int gap;//間距or增量
     for (gap = length/2; gap>0; gap/=2) { //gap->1 共分幾次
         for (int i=gap; i<length; i++) {//從gap個(gè)元素開始禀酱,直接插入排序
             if (arr[i] < arr[i-gap]) {
                 int tmp = arr[i];
                 int k = i-gap;
                 while (k>=0 && arr[k] > tmp) {
                     arr[k+gap] = arr[k];
                     k-=gap;
                 }
                 arr[k+gap] = tmp;
             }
         }
     }
}

OC實(shí)現(xiàn)

- (NSArray *)shellSort:(NSMutableArray *)arr {
    int length = arr.count;
    int gap;
    for (gap = length/2; gap>0; gap/=2) {
        for (int i = gap; i < length; i++) {
            if ([arr[i] intValue] < [arr[i-gap] intValue]) {
                NSNumber *tmp = arr[i];
                int k = i-gap;
                while (k>=0 && [arr[k] intValue] > tmp.intValue) {
                    arr[k+gap] = arr[k];
                    k-=gap;
                }
                arr[k+gap] = tmp;
            }
        }
    }
    return arr.copy;
}

以下實(shí)現(xiàn)來源于網(wǎng)絡(luò),未驗(yàn)證

c++實(shí)現(xiàn)

void shell_sort(const int start, const int end) {
    int increment = end - start + 1;    //初始化劃分增量
    int temp{ 0 };
    do {    //每次減小增量牧嫉,直到increment = 1
        increment = increment / 3 + 1;
        for (int i = start + increment; i <= end; ++i) {    //對(duì)每個(gè)劃分進(jìn)行直接插入排序
            if (numbers[i - increment] > numbers[i]) {
                temp = numbers[i];
                int j = i - increment;
                do {    //移動(dòng)元素并尋找位置
                    numbers[j + increment] = numbers[j];
                    j -= increment;
                } while (j >= start && numbers[j] > temp);
                numbers[j + increment] = temp;  //插入元素
            }
        }
    } while (increment > 1);
}

js實(shí)現(xiàn)

function shellSort(arr) {
    var len = arr.length,
        temp,
        gap = 1;
    while(gap < len/3) {          //動(dòng)態(tài)定義間隔序列
        gap =gap*3+1;
    }
    for (gap; gap > 0; gap = Math.floor(gap/3)) {
        for (var i = gap; i < len; i++) {
            temp = arr[i];
            for (var j = i-gap; j >= 0 && arr[j] > temp; j-=gap) {
                arr[j+gap] = arr[j];
            }
            arr[j+gap] = temp;
        }
    }
    return arr;
}

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

def shellSort(arr):
    import math
    gap=1
    while(gap < len(arr)/3):
        gap = gap*3+1
    while gap > 0:
        for i in range(gap,len(arr)):
            temp = arr[i]
            j = i-gap
            while j >=0 and arr[j] > temp:
                arr[j+gap]=arr[j]
                j-=gap
            arr[j+gap] = temp
        gap = math.floor(gap/3)
    return arr
}

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

func shellSort(arr []int) []int {
    length := len(arr)
    gap := 1
    for gap < gap/3 {
        gap = gap*3 + 1
    }
    for gap > 0 {
        for i := gap; i < length; i++ {
            temp := arr[i]
            j := i - gap
            for j >= 0 && arr[j] > temp {
                arr[j+gap] = arr[j]
                j -= gap
            }
            arr[j+gap] = temp
        }
        gap = gap / 3
    }
    return arr
}

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

public class ShellSort implements IArraySort {
    @Override
    public int[] sort(int[] sourceArray) throws Exception {
        // 對(duì) arr 進(jìn)行拷貝剂跟,不改變參數(shù)內(nèi)容
        int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);

        int gap = 1;
        while (gap < arr.length) {
            gap = gap * 3 + 1;
        }
        while (gap > 0) {
            for (int i = gap; i < arr.length; i++) {
                int tmp = arr[i];
                int j = i - gap;
                while (j >= 0 && arr[j] > tmp) {
                    arr[j + gap] = arr[j];
                    j -= gap;
                }
                arr[j + gap] = tmp;
            }
            gap = (int) Math.floor(gap / 3);
        }
        return arr;
    }
}

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

function shellSort($arr)
{
    $len = count($arr);
    $temp = 0;
    $gap = 1;
    while($gap < $len / 3) {
        $gap = $gap * 3 + 1;
    }
    for ($gap; $gap > 0; $gap = floor($gap / 3)) {
        for ($i = $gap; $i < $len; $i++) {
            $temp = $arr[$i];
            for ($j = $i - $gap; $j >= 0 && $arr[$j] > $temp; $j -= $gap) {
                $arr[$j+$gap] = $arr[$j];
            }
            $arr[$j+$gap] = $temp;
        }
    }
    return $arr;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市酣藻,隨后出現(xiàn)的幾起案子曹洽,更是在濱河造成了極大的恐慌,老刑警劉巖辽剧,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件送淆,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡怕轿,警方通過查閱死者的電腦和手機(jī)偷崩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門辟拷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人环凿,你說我怎么就攤上這事》欧裕” “怎么了智听?”我有些...
    開封第一講書人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長渡紫。 經(jīng)常有香客問我到推,道長,這世上最難降的妖魔是什么惕澎? 我笑而不...
    開封第一講書人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任莉测,我火速辦了婚禮,結(jié)果婚禮上唧喉,老公的妹妹穿的比我還像新娘捣卤。我一直安慰自己,他們只是感情好八孝,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開白布董朝。 她就那樣靜靜地躺著,像睡著了一般干跛。 火紅的嫁衣襯著肌膚如雪子姜。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,292評(píng)論 1 301
  • 那天楼入,我揣著相機(jī)與錄音哥捕,去河邊找鬼。 笑死嘉熊,一個(gè)胖子當(dāng)著我的面吹牛遥赚,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播阐肤,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼鸽捻,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了泽腮?” 一聲冷哼從身側(cè)響起御蒲,我...
    開封第一講書人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎诊赊,沒想到半個(gè)月后厚满,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡碧磅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年碘箍,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了遵馆。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡丰榴,死狀恐怖货邓,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情四濒,我是刑警寧澤换况,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站盗蟆,受9級(jí)特大地震影響戈二,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜喳资,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一觉吭、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧仆邓,春花似錦鲜滩、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至察署,卻和暖如春闷游,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背贴汪。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來泰國打工脐往, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人扳埂。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓业簿,卻偏偏與公主長得像,于是被迫代替她去往敵國和親阳懂。 傳聞我的和親對(duì)象是個(gè)殘疾皇子梅尤,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 前言 希爾排序算法其本質(zhì)就是插入排序,是直接插入排序算法的一種改進(jìn)岩调,因 D.L shell 于 1959 年提出而...
    tingxins閱讀 1,180評(píng)論 0 3
  • 前面一口氣寫了冒泡巷燥、選擇、插入三個(gè)排序算法号枕,感覺今天和他們死磕上了缰揪。。葱淳。就不該十一點(diǎn)多還看了幾眼钝腺。抛姑。。然后又掉坑里...
    noonbiteun閱讀 1,342評(píng)論 0 8
  • 1959年Shell發(fā)明,第一個(gè)突破O(n2)的排序算法毫目,是簡單插入排序的改進(jìn)版蔬啡。它與插入排序的不同之處在于,它會(huì)...
    Awanwan閱讀 333評(píng)論 0 0
  • 1. 算法描述 1959年Shell發(fā)明蒜茴,第一個(gè)突破O(n2)的排序算法星爪,是簡單插入排序的改進(jìn)版浆西。它與插入排序的不...
    有毒的程序猿閱讀 207評(píng)論 0 0
  • 聲明:算法和數(shù)據(jù)結(jié)構(gòu)的文章均是作者從github上翻譯過來粉私,為方便大家閱讀。如果英語閱讀能力強(qiáng)的朋友近零,可以直接到s...
    UnsanYL閱讀 717評(píng)論 1 3