歸并排序

歸并排序

歸并排序的時(shí)間復(fù)雜度是O(n*log2n)就斤,是穩(wěn)定的

歸并排序的思想是分治法(Divide and Conquer)

首先思考一個(gè)問(wèn)題舷蟀,已經(jīng)排序的兩個(gè)數(shù)組如何融合為一個(gè)有序數(shù)組
數(shù)組a靡努,數(shù)組b撑蒜,b中的第一個(gè)與a中的第一個(gè)比較,小的那個(gè)放到臨時(shí)數(shù)組c中,一旦數(shù)組a或者b已經(jīng)遍歷完了粱檀,那么另外一個(gè)剩下的數(shù)組全部放到臨時(shí)數(shù)組即可

1.融合兩個(gè)已經(jīng)排序的數(shù)組片段

融合兩個(gè)已經(jīng)排序的數(shù)組段代碼如下:

/**
*a為排序數(shù)組,left為已排序左片段的下標(biāo)漫玄,mid為已排序左片段的最后一個(gè)下標(biāo)
*茄蚯,right為已排序的右片段的最后一個(gè)下標(biāo),tem為臨時(shí)數(shù)組
*
**/
private static void mergeArray(int[] a ,int left,int mid,int right,int[] tem){
        //i為待會(huì)要進(jìn)行比較的左數(shù)組的游標(biāo),j為右數(shù)組的游標(biāo)第队,k為臨時(shí)數(shù)組的游標(biāo)
        int i = left;
        int j = mid + 1;
        int k = left;
        
        //一旦某個(gè)數(shù)組片段已經(jīng)遍歷完了哮塞,退出循環(huán)
        while(i <= mid && j <= right){
            if(a[i] < a[j]){
                tem[k] = a[i];
                i++;
                k++;
            }else{
                tem[k] = a[j];
                j++;
                k++;
            }
        }
        
        //把那個(gè)未遍歷完的數(shù)組片段全部加到臨時(shí)數(shù)組即可
        while(i <= mid){
            tem[k] = a[i];
            i++;
            k++;
        }
        
        //與上一個(gè)while循環(huán)只會(huì)執(zhí)行其一,因?yàn)橹豢赡艹霈F(xiàn)一個(gè)片段有剩余
        while(j <= right){
            tem[k] = a[j];
            j++;
            k++;
        }
        
        //把臨時(shí)數(shù)組放回到原數(shù)組
        for(;left <= right;left++){
            a[left] = tem[left];
        }
    }

2.遞歸劃分出已排序的兩個(gè)數(shù)組片段

如何遞歸劃分出已排序的兩個(gè)數(shù)組片段凳谦?
如果那個(gè)數(shù)組片段只有一個(gè)元素忆畅,就可以看成它是有序的,以下代碼遞歸出這個(gè)片段:

    private static void mergeSortMethod(int [] array,int start ,int end ,int[] tem){
        //數(shù)組元素大于1的時(shí)候才進(jìn)行遞歸分割尸执。等于1就直接有序了
        if(start < end){
            //將一個(gè)數(shù)組分為兩段家凯,mid為左邊的最后一個(gè)下標(biāo)
            int mid = (start + end) / 2;
            //對(duì)左邊再進(jìn)行分割
            mergeSortMethod(array, start, mid, tem);
            //對(duì)右邊再進(jìn)行分割
            mergeSortMethod(array, mid + 1, end, tem);
            //歸并兩個(gè)已排序數(shù)組
            mergeArray(array, start, mid, end, tem);
        }
    

當(dāng)片段長(zhǎng)度為1的數(shù)組進(jìn)入上述方法時(shí)候,遞歸停止如失,然后進(jìn)行第一次的方法調(diào)用

mergeArray(array, start, mid, end, tem);

然后繼續(xù)上一層的遞歸出棧绊诲。最后完成整個(gè)調(diào)用。

3.調(diào)用mergeArray()方法:

public static void mergeSort(int[] array){
                //這場(chǎng)的臨時(shí)數(shù)組用的是同一個(gè)褪贵,導(dǎo)致空間復(fù)雜度是O(n)
        mergeSortMethod(array, 0, array.length - 1, new int[array.length]);
    }

4.完整代碼:


public class MergeSortSenninha {
    public static void main(String[] arg){
        int [] left = {1,2,5,7,889,3,4,6,7};
        mergeSort(left);
        print(left);
    }
    
    
    private static void mergeArray(int[] a ,int left,int mid,int right,int[] tem){
        int i = left;
        int j = mid + 1;
        int k = left;
        
        while(i <= mid && j <= right){
            if(a[i] < a[j]){
                tem[k] = a[i];
                i++;
                k++;
            }else{
                tem[k] = a[j];
                j++;
                k++;
            }
        }
        
        while(i <= mid){
            tem[k] = a[i];
            i++;
            k++;
        }
        
        while(j <= right){
            tem[k] = a[j];
            j++;
            k++;
        }
        
        for(;left <= right;left++){
            a[left] = tem[left];
        }
    }
    
    public static void mergeSort(int[] array){
        mergeSortMethod(array, 0, array.length - 1, new int[array.length]);
    }
    
    private static void mergeSortMethod(int [] array,int start ,int end ,int[] tem){
        if(start < end){
            int mid = (start + end) / 2;
            mergeSortMethod(array, start, mid, tem);
            mergeSortMethod(array, mid + 1, end, tem);
            mergeArray(array, start, mid, end, tem);
        }
    }
    
    
    
    public static void print(int[] array){
        for(int i : array){
            System.out.print(i + " ");
        }
        System.out.println("");
    }
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末掂之,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子脆丁,更是在濱河造成了極大的恐慌世舰,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,820評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件槽卫,死亡現(xiàn)場(chǎng)離奇詭異跟压,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)歼培,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門震蒋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人躲庄,你說(shuō)我怎么就攤上這事查剖。” “怎么了读跷?”我有些...
    開(kāi)封第一講書人閱讀 168,324評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵梗搅,是天一觀的道長(zhǎng)禾唁。 經(jīng)常有香客問(wèn)我效览,道長(zhǎng),這世上最難降的妖魔是什么荡短? 我笑而不...
    開(kāi)封第一講書人閱讀 59,714評(píng)論 1 297
  • 正文 為了忘掉前任丐枉,我火速辦了婚禮,結(jié)果婚禮上掘托,老公的妹妹穿的比我還像新娘瘦锹。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,724評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布弯院。 她就那樣靜靜地躺著辱士,像睡著了一般。 火紅的嫁衣襯著肌膚如雪听绳。 梳的紋絲不亂的頭發(fā)上颂碘,一...
    開(kāi)封第一講書人閱讀 52,328評(píng)論 1 310
  • 那天,我揣著相機(jī)與錄音椅挣,去河邊找鬼头岔。 笑死,一個(gè)胖子當(dāng)著我的面吹牛鼠证,可吹牛的內(nèi)容都是我干的峡竣。 我是一名探鬼主播,決...
    沈念sama閱讀 40,897評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼量九,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼适掰!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起荠列,我...
    開(kāi)封第一講書人閱讀 39,804評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤攻谁,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后弯予,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體戚宦,經(jīng)...
    沈念sama閱讀 46,345評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,431評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了贰镣。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片命迈。...
    茶點(diǎn)故事閱讀 40,561評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖艳汽,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情对雪,我是刑警寧澤河狐,帶...
    沈念sama閱讀 36,238評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站瑟捣,受9級(jí)特大地震影響馋艺,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜迈套,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,928評(píng)論 3 334
  • 文/蒙蒙 一捐祠、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧桑李,春花似錦踱蛀、人聲如沸窿给。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,417評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)崩泡。三九已至,卻和暖如春猬膨,著一層夾襖步出監(jiān)牢的瞬間允华,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,528評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工寥掐, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留靴寂,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,983評(píng)論 3 376
  • 正文 我出身青樓召耘,卻偏偏與公主長(zhǎng)得像百炬,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子污它,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,573評(píng)論 2 359

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

  • 數(shù)據(jù)結(jié)構(gòu)與算法--歸并排序 歸并排序 歸并排序基于一種稱為“歸并”的簡(jiǎn)單操作剖踊。比如考試可能會(huì)分年級(jí)排名和班級(jí)排名,...
    sunhaiyu閱讀 882評(píng)論 0 6
  • Q:什么是歸并排序衫贬?A:它是建立在歸并操作上的一種有效的排序算法德澈;是采用分治法的一個(gè)非常典型的應(yīng)用;是一種穩(wěn)定的 ...
    TinyDolphin閱讀 2,945評(píng)論 5 4
  • 歸并排序 所謂歸并固惯,就是將兩個(gè)或兩個(gè)以上的有序表合并成一個(gè)新的有序表梆造。如下圖所示,有兩個(gè)已經(jīng)排好序的有序表A[1]...
    JackChen1024閱讀 2,365評(píng)論 0 4
  • 一.兩個(gè)有序數(shù)組的排順 如果有兩個(gè)有序的數(shù)組合并為一個(gè)有序數(shù)組葬毫,我們可以用下面的代碼實(shí)現(xiàn): 其中數(shù)組a,b為我們已...
    Geeks_Liu閱讀 271評(píng)論 0 1
  • 思路 歸并排序的思想是先將數(shù)組分散為小數(shù)組分別排序镇辉,然后將結(jié)果歸并起來(lái)。 原地歸并的抽象方法 將兩個(gè)已經(jīng)排序好的數(shù)...
    不可思議的Mark閱讀 4,097評(píng)論 12 31