數(shù)據(jù)結(jié)構(gòu)與算法--分治法、歸并排序

分治法

分治法的思想是:將原問題分解成若干個規(guī)模較小但是與原問題類似的問題剩彬,遞歸地求解這些子問題盛末,然后再合并這些子問題的解來建立原問題的解弹惦。

分治法在每層遞歸時都有三個步驟:

  • 分解: 將原問題分解為若干個子問題,這些問題是原問題的規(guī)模較小的實(shí)例
  • 解決: 遞歸求解子問題悄但,若子問題規(guī)模足夠小棠隐,則直接求解
  • 合并: 合并這些子問題的解成原問題的解。

歸并排序

歸并排序就是采用分治法的思想檐嚣。

  • 分解: 分解待排序的n個元素的序列成各具n/2個元素的兩個子序列助泽。
  • 解決: 遞歸排序兩個子序列。
  • 合并: 合并兩個已排序的子序列以產(chǎn)生已排序的答案嚎京。

其遞歸思想如下圖所示

3eb110a0a8f74306b4b1d8803568aa5cpng

將數(shù)組分為含有n/2個元素的兩個數(shù)組嗡贺,然后分別遞歸排序,然后再次拆分鞍帝,直到最后只剩一個元素诫睬。然后開始?xì)w并。這個算法的難點(diǎn)在于子序列的合并帕涌,合并思想如下

42f1960cdb5f4366acfcc35c4f9497c9png

首先需要創(chuàng)建一個數(shù)組摄凡,我們記為S,數(shù)組的長度為兩個子序列之和蚓曼。從兩個子序列的最左端開始亲澡,誰的元素小(大)就將誰的放入到S中辟躏。

歸并排序代碼實(shí)現(xiàn)

public class MergeSort {

    public static int[] sort(int[] arr, int start, int end) {
        if (start == end) {
            // 如果開始索引和結(jié)束索引相等谷扣,說明只需處理一個元素,所以直接返回此元素即可捎琐。
            return new int[] {arr[start]};
        } else {
            // 這里減一不減一都可以会涎,如果減一是把奇數(shù)元素的子序列放到了最右邊,否則是放到了最左邊來處理
            // 等價于(end-start)/2瑞凑,由于位運(yùn)算速度更快末秃,所以這里使用位運(yùn)算。
            int half = ((end - start - 1) >> 1);
            int[] left = sort(arr, start, start + half);
            int[] right = sort(arr, start + half + 1, end);

            // 合并子序列
            int maxLength = left.length + right.length;
            int[] mergeArr = new int[maxLength];
            int lIndex = 0;
            int rIndex = 0;
            for (int i = 0; i < maxLength; i++) {
                if (lIndex < left.length && rIndex < right.length) {
                    if (left[lIndex] <= right[rIndex]) {
                        mergeArr[i] = left[lIndex];
                        lIndex++;
                    } else {
                        mergeArr[i] = right[rIndex];
                        rIndex++;
                    }
                } else if (lIndex < left.length) {
                    mergeArr[i] = left[lIndex];
                    lIndex++;
                } else {
                    mergeArr[i] = right[rIndex];
                    rIndex++;
                }

            }
            return mergeArr;
        }
    }

    public static void main(String[] args) {
        int[] arr = {2, 5, 1, 8, 9, 7, 6, 12, 4};
        int[] sortRes = sort(arr, 0, arr.length - 1);
        for (int i : sortRes) {
            System.out.printf("%d\t", i);
        }
        System.out.println();
    }
}

時間復(fù)雜度分析

我們先看遞歸深度籽御,從上面的圖中我們能看出遞歸深度應(yīng)該是log_2 n + 1练慕。有根節(jié)點(diǎn)所以加一惰匙,最后一級如果不是滿樹的狀態(tài)會被忽略掉。

設(shè)c = \log_2 n铃将,那么遞歸式的和為\sum_{i=0}^{c} 2^i(從0開始是為了方便計算)项鬼。此算法中的基本操作就是合并,假設(shè)第一層的時間復(fù)雜度是Cn次劲阎,第二層每個遞歸就是Cn/2绘盟,以此類推,最后得到總的時間復(fù)雜度為:
\sum_{i=0}^{c} 2^i \times \frac{Cn}{2^i} = \sum_{i=0}^{c} Cn = (c + 1)Cn = Cnlog_2 n + Cn
舍去常數(shù)項(xiàng)和對算法影響較小的項(xiàng)最終就是O(nlog_2n)或者寫為O(nlgn)在算法中lgn通常表示以2為底n的對數(shù)悯仙。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末龄毡,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子锡垄,更是在濱河造成了極大的恐慌沦零,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件货岭,死亡現(xiàn)場離奇詭異路操,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)茴她,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進(jìn)店門寻拂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人丈牢,你說我怎么就攤上這事∶樯常” “怎么了己沛?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長距境。 經(jīng)常有香客問我申尼,道長,這世上最難降的妖魔是什么垫桂? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任师幕,我火速辦了婚禮,結(jié)果婚禮上诬滩,老公的妹妹穿的比我還像新娘霹粥。我一直安慰自己,他們只是感情好疼鸟,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布后控。 她就那樣靜靜地躺著,像睡著了一般空镜。 火紅的嫁衣襯著肌膚如雪浩淘。 梳的紋絲不亂的頭發(fā)上捌朴,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天,我揣著相機(jī)與錄音张抄,去河邊找鬼砂蔽。 笑死,一個胖子當(dāng)著我的面吹牛署惯,可吹牛的內(nèi)容都是我干的察皇。 我是一名探鬼主播,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼泽台,長吁一口氣:“原來是場噩夢啊……” “哼什荣!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起怀酷,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤稻爬,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后蜕依,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體桅锄,經(jīng)...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年样眠,在試婚紗的時候發(fā)現(xiàn)自己被綠了友瘤。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,664評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡檐束,死狀恐怖辫秧,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情被丧,我是刑警寧澤盟戏,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站甥桂,受9級特大地震影響柿究,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜黄选,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一蝇摸、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧办陷,春花似錦貌夕、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至殃恒,卻和暖如春植旧,著一層夾襖步出監(jiān)牢的瞬間辱揭,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工病附, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留问窃,地道東北人。 一個月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓完沪,卻偏偏與公主長得像域庇,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子覆积,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,675評論 2 359

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