常見排序算法(6)--歸并排序(非遞歸版)

非遞歸歸并排序算法

非遞歸排序與遞歸排序相反,將一個元素與相鄰元素構(gòu)成有序數(shù)組锯仪,再與旁邊數(shù)組構(gòu)成有序數(shù)組泵督,直至整個數(shù)組有序。


代碼實(shí)現(xiàn)
// 歸并排序非遞歸版
void MergeSort2(int *arr,int length)
{
    int k = 1;/*k用來表示每次k個元素歸并*/
    int *temp = (int *)malloc(sizeof(int) * length);
    while(k < length)
    {
        MergePass(arr, k, length, temp);
        k *= 2;
    }
    free(temp);
}
void MergePass(int *arr, int k, int n, int *temp)
{
    int i = 0;
    //從前往后,將2個長度為k的子序列合并為1個
    while(i < n - 2*k + 1)
    {
        merge(arr, i, i + k-1, i + 2*k - 1, temp);
        i += 2*k;
    }
    //合并有序的左半部分以及不及一個步長的右半部分
    if(i < n - k )
    {
        merge(arr, i, i+k-1, n-1, temp);
    }
    
}

直接說代碼吧庶喜。MergeSort2函數(shù)就是歸并排序的非遞歸方法小腊,里面就是個while循環(huán),單看MergeSort2方法可能不太明白久窟,我們要先明白核心方法MergePass做了什么秩冈。

while循環(huán)的解釋

MergePass里面的while循環(huán),其實(shí)就是把將2個長度為k的子序列合并為1個(其中merge方法跟上篇文章的遞歸版歸并排序的merge是完全一樣的)斥扛。最開始我看到這個方法的時候也看不懂入问,啥i < n - 2*k + 1,為啥又是i, i + k-1, i + 2*k - 1這3個數(shù)稀颁。其實(shí)它是把a(bǔ)rr數(shù)組分為了這樣的小序列芬失。如下標(biāo)為[i,i+k-1],這是左子序列,剛好有k個元素匾灶,右子序列為[i+k,i+2k-1]棱烂,也是k個。如果數(shù)組的元素個數(shù)n剛好是2k的倍數(shù)那是最好的阶女,各個長度為k的左右子序列分別合并颊糜,沒有遺留下不能配對的元素。但是一般不會這么湊巧秃踩,一般n都不會是2k的倍數(shù)衬鱼,所以i < n - 2*k + 1等價于i + 2k -1 < n等價于i + 2k -1 <= n-1,其中i + 2k -1剛好是右子序列的右邊界憔杨,這個i + 2k -1 <= n-1保證了把數(shù)組中的可以配對的子序列全都剝離出來了馁启。舉個例子,假設(shè)k=1芍秆,某數(shù)組有7個元素,前4個元素可以完全配對翠勉。

if判斷的解釋

如果n不是2k的倍數(shù)妖啥,那么所以余下的元素個數(shù)就是在1到2k-1個之間。下面的if就是解決這部分的对碌。為什么有i < n - k這個判斷條件荆虱?其實(shí)如果余下多余的元素,也不是一定要在這次的MergePass方法中處理。只有當(dāng)余下的元素的個數(shù)多于k個時(也就是存在右半部分的子序列怀读,1=<右半部分的個數(shù)<=k-1)需要把有k個元素的左序列與不足k個元素的右序列merge诉位。假設(shè)余下的元素個數(shù)<=k個,那么在這次MergePass不用處理(會在最后一次MergePass中被merge)菜枷。左序列的右邊界是i+k-1一定要小于最后一個元素的下標(biāo)n-1苍糠,所以有i+k-1<n-1,所以有i < n - k這個條件啤誊。這個判斷條件就保證了肯定存在右子序列岳瞭。

MergeSort2方法的邊界條件的解釋

MergeSort2方法中有個while循環(huán),它的邊界條件是k < length蚊锹。這里我們探究一下瞳筏,可以寫成k <= length嗎?其實(shí)k的最大值是可以求出來的牡昆,現(xiàn)在我們就來算k的最大值姚炕。如果數(shù)組的個數(shù)的length剛好是2n,如2丢烘,4柱宦,8,16這樣的铅协,那么最后的k就等于 length/2 捷沸。如果length不是2n這樣的數(shù),那么最后的k就等于2n狐史,其中n=log(length)的整數(shù)部分痒给;如length=34,n=5骏全,k就等于32苍柏。k其實(shí)就是小于length的最大的2n的數(shù)。所以這里的邊界條件寫k < length是對的姜贡。

其實(shí)非遞歸歸并排序算法的代碼也不多试吁,但是比較難理解,不過我覺得我前面的解釋的很清楚了楼咳,如果暫時看不懂熄捍,多讀幾遍。還是不懂的話可以在評論中@我母怜。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末余耽,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子苹熏,更是在濱河造成了極大的恐慌碟贾,老刑警劉巖币喧,帶你破解...
    沈念sama閱讀 218,451評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異袱耽,居然都是意外死亡杀餐,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評論 3 394
  • 文/潘曉璐 我一進(jìn)店門朱巨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來史翘,“玉大人,你說我怎么就攤上這事蔬崩《褡” “怎么了?”我有些...
    開封第一講書人閱讀 164,782評論 0 354
  • 文/不壞的土叔 我叫張陵沥阳,是天一觀的道長跨琳。 經(jīng)常有香客問我,道長桐罕,這世上最難降的妖魔是什么脉让? 我笑而不...
    開封第一講書人閱讀 58,709評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮功炮,結(jié)果婚禮上溅潜,老公的妹妹穿的比我還像新娘。我一直安慰自己薪伏,他們只是感情好滚澜,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,733評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著嫁怀,像睡著了一般设捐。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上塘淑,一...
    開封第一講書人閱讀 51,578評論 1 305
  • 那天萝招,我揣著相機(jī)與錄音,去河邊找鬼存捺。 笑死槐沼,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的捌治。 我是一名探鬼主播岗钩,決...
    沈念sama閱讀 40,320評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼肖油!你這毒婦竟也來了凹嘲?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,241評論 0 276
  • 序言:老撾萬榮一對情侶失蹤构韵,失蹤者是張志新(化名)和其女友劉穎周蹭,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體疲恢,經(jīng)...
    沈念sama閱讀 45,686評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡凶朗,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,878評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了显拳。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片棚愤。...
    茶點(diǎn)故事閱讀 39,992評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖杂数,靈堂內(nèi)的尸體忽然破棺而出宛畦,到底是詐尸還是另有隱情,我是刑警寧澤揍移,帶...
    沈念sama閱讀 35,715評論 5 346
  • 正文 年R本政府宣布次和,位于F島的核電站,受9級特大地震影響那伐,放射性物質(zhì)發(fā)生泄漏踏施。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,336評論 3 330
  • 文/蒙蒙 一罕邀、第九天 我趴在偏房一處隱蔽的房頂上張望畅形。 院中可真熱鬧,春花似錦诉探、人聲如沸日熬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,912評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽竖席。三九已至,卻和暖如春阳液,著一層夾襖步出監(jiān)牢的瞬間怕敬,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,040評論 1 270
  • 我被黑心中介騙來泰國打工帘皿, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留东跪,地道東北人。 一個月前我還...
    沈念sama閱讀 48,173評論 3 370
  • 正文 我出身青樓鹰溜,卻偏偏與公主長得像虽填,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子曹动,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,947評論 2 355

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

  • 概述 排序有內(nèi)部排序和外部排序斋日,內(nèi)部排序是數(shù)據(jù)記錄在內(nèi)存中進(jìn)行排序,而外部排序是因排序的數(shù)據(jù)很大墓陈,一次不能容納全部...
    蟻前閱讀 5,184評論 0 52
  • 總結(jié)一下常見的排序算法恶守。 排序分內(nèi)排序和外排序第献。內(nèi)排序:指在排序期間數(shù)據(jù)對象全部存放在內(nèi)存的排序。外排序:指在排序...
    jiangliang閱讀 1,346評論 0 1
  • 1.插入排序—直接插入排序(Straight Insertion Sort) 基本思想: 將一個記錄插入到已排序好...
    依依玖玥閱讀 1,254評論 0 2
  • 在C語言中,五種基本數(shù)據(jù)類型存儲空間長度的排列順序是: A)char B)char=int<=float C)ch...
    夏天再來閱讀 3,343評論 0 2
  • 萬丈紅塵三杯酒, 千秋大業(yè)一壺茶衫樊。 大家好飒赃,我是洛蘇。一個錦繡峨眉大山深入土生土長的女子科侈,深愛古典文化载佳,更愛...
    茶女落蘇閱讀 472評論 0 0