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

1、基本思想

分析歸并排序之前胯陋,我們先來(lái)了解一下分治算法蕊温。

分治算法的基本思想是將一個(gè)規(guī)模為N的問(wèn)題分解為K個(gè)規(guī)模較小的子問(wèn)題袱箱,這些子問(wèn)題相互獨(dú)立且與原問(wèn)題性質(zhì)相同。求出子問(wèn)題的解寿弱,就可得到原問(wèn)題的解犯眠。

分治算法的一般步驟:

  • 分解,將要解決的問(wèn)題劃分成若干規(guī)模較小的同類(lèi)問(wèn)題症革;
  • 求解筐咧,當(dāng)子問(wèn)題劃分得足夠小時(shí),用較簡(jiǎn)單的方法解決噪矛;
  • 合并量蕊,按原問(wèn)題的要求,將子問(wèn)題的解逐層合并構(gòu)成原問(wèn)題的解艇挨。

歸并排序是分治算法的典型應(yīng)用残炮。

歸并排序先將一個(gè)無(wú)序的N長(zhǎng)數(shù)組切成N個(gè)有序子序列(只有一個(gè)數(shù)據(jù)的序列認(rèn)為是有序序列),然后兩兩合并缩滨,再將合并后的N/2(或者N/2 + 1)個(gè)子序列繼續(xù)進(jìn)行兩兩合并势就,以此類(lèi)推得到一個(gè)完整的有序數(shù)組。過(guò)程如下圖所示:

1.png

2脉漏、實(shí)例

歸并排序的核心思想是將兩個(gè)有序的數(shù)組歸并到另一個(gè)數(shù)組中苞冯,所以需要開(kāi)辟額外的空間。

第一步要理清歸并的思路侧巨。假設(shè)現(xiàn)在有兩個(gè)有序數(shù)組A和B舅锄,要將兩者有序地歸并到數(shù)組C中。我們用一個(gè)實(shí)例來(lái)推演:

2.png

上圖中司忱,A數(shù)組中有四個(gè)元素皇忿,B數(shù)組中有六個(gè)元素,首先比較A坦仍、B中的第一個(gè)元素鳍烁,將較小的那個(gè)放到C數(shù)組的第一位,因?yàn)樵撛鼐褪茿繁扎、B所有元素中最小的幔荒。上例中,7小于23锻离,所以將7放到了C中铺峭。

然后墓怀,用23與B中的其他元素比較汽纠,如果小于23,繼續(xù)按順序放到C中傀履;如果大于23虱朵,則將23放入C中莉炉。

23放入C中之后,用23之后的47作為基準(zhǔn)元素碴犬,與B中的其他元素繼續(xù)比較絮宁,重復(fù)上面的步驟。

如果有一個(gè)數(shù)組的元素已經(jīng)全部復(fù)制到C中了服协,那么將另一個(gè)數(shù)組中的剩余元素依次插入C中即可绍昂。至此結(jié)束。

按照上面的思路偿荷,用java實(shí)現(xiàn):

    /**
     * 
     * - 歸并arrayA與arrayB到arrayC中
     * 
     * - @param arrayA 待歸并的數(shù)組A
     * 
     * - @param sizeA 數(shù)組A的長(zhǎng)度
     * 
     * - @param arrayB 待歸并的數(shù)組B
     * 
     * - @param sizeB 數(shù)組B的長(zhǎng)度
     * 
     * - @param arrayC 輔助歸并排序的數(shù)組
     */
    public static void merge(int[] arrayA, int sizeA, int[] arrayB, int sizeB, int[] arrayC) {

        int i = 0, j = 0, k = 0; // 分別當(dāng)作arrayA窘游、arrayB、arrayC的下標(biāo)指針

        while (i < sizeA && j < sizeB) { // 兩個(gè)數(shù)組都不為空
            if (arrayA[i] < arrayB[j]) { // 將兩者較小的那個(gè)放到arrayC中
                arrayC[k++] = arrayA[i++];
            } else {
                arrayC[k++] = arrayB[j++];
            }
        } // 該循環(huán)結(jié)束后跳纳,一個(gè)數(shù)組已經(jīng)完全復(fù)制到arrayC中了忍饰,另一個(gè)數(shù)組中還有元素

        // 后面的兩個(gè)while循環(huán)用于處理另一個(gè)不為空的數(shù)組
        while (i < sizeA) {
            arrayC[k++] = arrayA[i++];
        }

        while (j < sizeB) {
            arrayC[k++] = arrayA[j++];
        }

        for (int l = 0; l < arrayC.length; l++) { // 打印新數(shù)組中的元素
            System.out.print(arrayC[l] + "\t");
        }
    }

再歸并之前,還有一步工作需要提前做好寺庄,就是數(shù)組的分解艾蓝,可以通過(guò)遞歸的方法來(lái)實(shí)現(xiàn)。遞歸(Recursive)是算法設(shè)計(jì)中常用的思想斗塘。

這樣通過(guò)先遞歸的分解數(shù)組赢织,再合并數(shù)組就完成了歸并排序。完整的java代碼如下:

public class Sort {

    private int[] array; // 待排序的數(shù)組

    public Sort(int[] array) {
        this.array = array;
    }

    // 按順序打印數(shù)組中的元素
    public void display() {
        for (int i = 0; i < array.length; i++) {
            System.out.print(array[i] + "\t");
        }
        System.out.println();
    }

    // 歸并排序

    public void mergeSort() {

        int[] workSpace = new int[array.length]; // 用于輔助排序的數(shù)組
        recursiveMergeSort(workSpace, 0, workSpace.length - 1);
    }

    /**
     * 
     * - 遞歸的歸并排序
     * 
     * - @param workSpace 輔助排序的數(shù)組
     * 
     * - @param lowerBound 欲歸并數(shù)組段的最小下標(biāo)
     * 
     * - @param upperBound 欲歸并數(shù)組段的最大下標(biāo)
     */
    private void recursiveMergeSort(int[] workSpace, int lowerBound, int upperBound) {

        if (lowerBound == upperBound) { // 該段只有一個(gè)元素逛拱,不用排序
            return;
        } else {
            int mid = (lowerBound + upperBound) / 2;
            recursiveMergeSort(workSpace, lowerBound, mid); // 對(duì)低位段歸并排序
            recursiveMergeSort(workSpace, mid + 1, upperBound); // 對(duì)高位段歸并排序
            merge(workSpace, lowerBound, mid, upperBound);
            display();
        }
    }

    /**
     * 
     * - 對(duì)數(shù)組array中的兩段進(jìn)行合并敌厘,lowerBound~mid為低位段,mid+1~upperBound為高位段
     * 
     * - @param workSpace 輔助歸并的數(shù)組朽合,容納歸并后的元素
     * 
     * - @param lowerBound 合并段的起始下標(biāo)
     * 
     * - @param mid 合并段的中點(diǎn)下標(biāo)
     * 
     * - @param upperBound 合并段的結(jié)束下標(biāo)
     */
    private void merge(int[] workSpace, int lowerBound, int mid, int upperBound) {

        int lowBegin = lowerBound; // 低位段的起始下標(biāo)
        int lowEnd = mid; // 低位段的結(jié)束下標(biāo)
        int highBegin = mid + 1; // 高位段的起始下標(biāo)
        int highEnd = upperBound; // 高位段的結(jié)束下標(biāo)
        int j = 0; // workSpace的下標(biāo)指針
        int n = upperBound - lowerBound + 1; // 歸并的元素總數(shù)

        while (lowBegin <= lowEnd && highBegin <= highEnd) {
            if (array[lowBegin] < array[highBegin]) { // 將兩者較小的那個(gè)放到workSpace中
                workSpace[j++] = array[lowBegin++];
            } else {
                workSpace[j++] = array[highBegin++];
            }
        }

        while (lowBegin <= lowEnd) {
            workSpace[j++] = array[lowBegin++];
        }

        while (highBegin <= highEnd) {
            workSpace[j++] = array[highBegin++];
        }

        for (j = 0; j < n; j++) { // 將歸并好的元素復(fù)制到array中
            array[lowerBound++] = workSpace[j];
        }

    }
}

用以下代碼測(cè)試:

int [] a = {6,2,7,4,8,1,5,3};
Sort sort = new Sort(a);
sort.mergeSort();

打印結(jié)果如下:

3.png

歸并的順序是這樣的:先將初始數(shù)組分為兩部分俱两,先歸并低位段,再歸并高位段曹步。對(duì)低位段與高位段繼續(xù)分解宪彩,低位段分解為更細(xì)分的一對(duì)低位段與高位段,高位段同樣分解為更細(xì)分的一對(duì)低位段與高位段讲婚,依次類(lèi)推尿孔。

上例中,第一步筹麸,歸并的是6與2活合,第二步歸并的是7和4,第三部歸并的是前兩步歸并好的子段[2,6]與[4,7]物赶。至此白指,數(shù)組的左半部分(低位段)歸并完畢,然后歸并右半部分(高位段)酵紫。

所以第四步歸并的是8與1告嘲,第四部歸并的是5與3错维,第五步歸并的是前兩步歸并好的字段[1,8]與[3,5]。至此橄唬,數(shù)組的右半部分歸并完畢赋焕。

最后一步就是歸并數(shù)組的左半部分[2,4,6,7]與右半部分[1,3,5,8]。

歸并排序結(jié)束仰楚。

3隆判、遞歸

在本文開(kāi)始對(duì)歸并排序的描述中,第一躺歸并是對(duì)所有相鄰的兩個(gè)元素歸并結(jié)束之后僧界,才進(jìn)行下一輪歸并蜜氨,并不是先歸并左半部分,再歸并右半部分捎泻,但是程序的執(zhí)行順序與我們對(duì)歸并排序的分析邏輯不一致飒炎,所以理解起來(lái)有些困難。

下面結(jié)合代碼與圖例來(lái)詳細(xì)分析一下歸并排序的過(guò)程笆豁。

虛擬機(jī)棧(VM Stack)是描述Java方法執(zhí)行的內(nèi)存模型郎汪,每一次方法的調(diào)用都伴隨著一次壓棧、出棧操作闯狱。

我們要排序的數(shù)組為:

int [] a = {6,2,7,4,8,1,5,3}

當(dāng)main()方法調(diào)用mergeSort()方法時(shí)煞赢,被調(diào)用的方法被壓入棧中,然后程序進(jìn)入mergeSort()方法:

    public void mergeSort() {
        int[] workSpace = new int[array.length]; // 用于輔助排序的數(shù)組
        recursiveMergeSort(workSpace, 0, workSpace.length - 1);
    }

此時(shí)哄孤,mergeSort()又調(diào)用了recursiveMergeSort(workSpace,0,7)方法照筑,recursiveMergeSort(workSpace,0,7)方法也被壓入棧中,在mergeSort()之上瘦陈。

然后凝危,程序進(jìn)入到recursiveMergeSort(workSpace,0,7)方法:

if (lowerBound == upperBound) { // 該段只有一個(gè)元素,不用排序
    return;
} else {
    int mid = (lowerBound + upperBound) / 2;
    recursiveMergeSort(workSpace, lowerBound, mid); // 對(duì)低位段歸并排序
    recursiveMergeSort(workSpace, mid + 1, upperBound); // 對(duì)高位段歸并排序
    merge(workSpace, lowerBound, mid, upperBound);
    display();
}

lowerBound參數(shù)值為0晨逝,upperBound參數(shù)值為7蛾默,不滿(mǎn)足lowerBound == upperBound的條件,所以方法進(jìn)入else分支捉貌,然后調(diào)用方法recursiveMergeSort(workSpace,0,3)支鸡,recursiveMergeSort(workSpace,0,3)被壓入棧中,此時(shí)棧的狀態(tài)如下:

4.png

然而,recursiveMergeSort(workSpace,0,3)不能立即返回趁窃,它在內(nèi)部又會(huì)調(diào)用recursiveMergeSort(workSpace,0,1)牧挣,recursiveMergeSort(workSpace,0,1)又調(diào)用了recursiveMergeSort(workSpace,0,0),此時(shí)醒陆,棧中的狀態(tài)如下:

5.png

程序運(yùn)行到這里瀑构,終于有一個(gè)方法可以返回了結(jié)果了——recursiveMergeSort(workSpace,0,0),該方法的執(zhí)行的邏輯是對(duì)數(shù)組中的下標(biāo)從0到0的元素進(jìn)行歸并统求,該段只有一個(gè)元素检碗,所以不用歸并,立即return码邻。

方法一旦return折剃,就意味著方法結(jié)束,recursiveMergeSort(workSpace,0,0)從棧中彈出像屋。這時(shí)候怕犁,程序跳到了代碼片段(二)中的第二行:recursiveMergeSort(workSpace,1,1),該方法入棧己莺,recursiveMergeSort(workSpace,0,0)類(lèi)似奏甫,不用歸并,直接返回凌受,方法出棧阵子。

這時(shí)候程度跳到了代碼片段(二)中的第三行:merge(workSpace,0,0,1),即對(duì)數(shù)組中的前兩個(gè)元素進(jìn)行合并(自然胜蛉,merge(workSpace,0,0,1)也伴隨著一次入棧與出棧)挠进。

至此,代碼片段(二)執(zhí)行完畢誊册,recursiveMergeSort(workSpace,0,1)方法出棧领突,程序跳到代碼片段(三)的第二行:recursiveMergeSort(workSpace,2,3),該方法是對(duì)數(shù)組中的第三個(gè)案怯、第四個(gè)元素進(jìn)行歸并君旦,與執(zhí)行recursiveMergeSort(workSpace,0,1)的過(guò)程類(lèi)似,最終會(huì)將第三個(gè)嘲碱、第四個(gè)元素歸并排序金砍。

然后,程序跳到程序跳到代碼片段(三)的第三行:merge(workSpace,0,1,3)麦锯,將前面已經(jīng)排好序的兩個(gè)子序列(第一第二個(gè)元素為一組捞魁、第三第四個(gè)元素為一組)合并。

然后recursiveMergeSort(workSpace,0,3)出棧离咐,程序跳到代碼片段(四)的第二行:recursiveMergeSort(workSpace,4,7)谱俭,對(duì)數(shù)組的右半部分的四個(gè)元素進(jìn)行歸并排序,伴隨著一系列的入棧宵蛀、出棧昆著,最后將后四個(gè)元素排好。此時(shí)术陶,數(shù)組的左半部分與右半部分已經(jīng)有序凑懂。

然后程序跳到代碼片段(四)第三行:merge(workSpace,0,3,7),對(duì)數(shù)組的左半部分與右半部分合并梧宫。

然后recursiveMergeSort(workSpace,4,7)出棧接谨,mergeSort()出棧摆碉,最后main()方法出棧,程序結(jié)束脓豪。

4巷帝、算法分析

先來(lái)分析一下復(fù)制的次數(shù)。

如果待排數(shù)組有8個(gè)元素扫夜,歸并排序需要分3層楞泼,第一層有四個(gè)包含兩個(gè)數(shù)據(jù)項(xiàng)的自數(shù)組,第二層包含兩個(gè)包含四個(gè)數(shù)據(jù)項(xiàng)的子數(shù)組笤闯,第三層包含一個(gè)8個(gè)數(shù)據(jù)項(xiàng)的子數(shù)組堕阔。合并子數(shù)組的時(shí)候,每一層的所有元素都要經(jīng)歷一次復(fù)制(從原數(shù)組復(fù)制到workSpace數(shù)組)颗味,復(fù)制總次數(shù)為3* 8=24次超陆,即層數(shù)乘以元素總數(shù)。

設(shè)元素總數(shù)為N浦马,則層數(shù)為log2N侥猬,復(fù)制總次數(shù)為N log2N

其實(shí)捐韩,除了從原數(shù)組復(fù)制到workSpace數(shù)組退唠,還需要從workSpace數(shù)組復(fù)制到原數(shù)組,所以荤胁,最終的復(fù)制復(fù)制次數(shù)為2Nlog2N瞧预。

在大O表示法中,常數(shù)可以忽略仅政,所以歸并排序的時(shí)間復(fù)雜度為O(N log2N)垢油。

一般來(lái)講,復(fù)制操作的時(shí)間消耗要遠(yuǎn)大于比較操作的時(shí)間消耗圆丹,時(shí)間復(fù)雜度是由復(fù)制次數(shù)主導(dǎo)的滩愁。

下面我們?cè)賮?lái)分析一下比較次數(shù)。

在歸并排序中辫封,比較次數(shù)總是比復(fù)制次數(shù)少一些∠跬鳎現(xiàn)在給定兩個(gè)各有四個(gè)元素的子數(shù)組,首先來(lái)看一下最壞情況和最好情況下的比較次數(shù)為多少倦微。

6.png

第一種情況妻味,數(shù)據(jù)項(xiàng)大小交錯(cuò),所以必須進(jìn)行7次比較欣福,第二種情況中责球,一個(gè)數(shù)組比另一個(gè)數(shù)組中的所有元素都要小,因此只需要4次比較。

當(dāng)歸并兩個(gè)子數(shù)組時(shí)雏逾,如果元素總數(shù)為N嘉裤,則最好情況下的比較次數(shù)為N/2,最壞情況下的比較次數(shù)為N-1栖博。

假設(shè)待排數(shù)組的元素總數(shù)為N屑宠,則第一層需要N/2次歸并,每次歸并的元素總數(shù)為2笛匙;則第一層需要N/4次歸并,每次歸并的元素總數(shù)為4犀变;則第一層需要N/8次歸并妹孙,每次歸并的元素總數(shù)為8……最后一次歸并次數(shù)為1,歸并的元素總數(shù)為N获枝〈勒總層數(shù)為log2N。

最好情況下的比較總數(shù)為:

N/2*(2/2)+ N/4*(4/2)+ N/8*(8/2)+...+1*(N/2) = (N/2)*log2N

最好情況下的比較總數(shù)為:

N/2*(2-1)+ N/4*(4-1)+ N/8*(8-1)+...+1*(N-1) = (N-N/2)+ (N-N/4)+(N-N/8)+...+(N-1) = N*log2N-(1+ N/2+N/4+..)< N*log2N

可見(jiàn)省店,比較次數(shù)介于(N/2)log2N與Nlog2N之間嚣崭。如果用大O表示法,時(shí)間復(fù)雜度也為O(Nlog2N)懦傍。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末雹舀,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子粗俱,更是在濱河造成了極大的恐慌说榆,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,183評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件寸认,死亡現(xiàn)場(chǎng)離奇詭異签财,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)偏塞,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)唱蒸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人灸叼,你說(shuō)我怎么就攤上這事神汹。” “怎么了古今?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,766評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵慎冤,是天一觀(guān)的道長(zhǎng)。 經(jīng)常有香客問(wèn)我沧卢,道長(zhǎng)蚁堤,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,854評(píng)論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮披诗,結(jié)果婚禮上撬即,老公的妹妹穿的比我還像新娘。我一直安慰自己呈队,他們只是感情好剥槐,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著宪摧,像睡著了一般粒竖。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上几于,一...
    開(kāi)封第一講書(shū)人閱讀 52,457評(píng)論 1 311
  • 那天蕊苗,我揣著相機(jī)與錄音,去河邊找鬼沿彭。 笑死朽砰,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的喉刘。 我是一名探鬼主播瞧柔,決...
    沈念sama閱讀 40,999評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼睦裳!你這毒婦竟也來(lái)了造锅?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,914評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤廉邑,失蹤者是張志新(化名)和其女友劉穎备绽,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體鬓催,經(jīng)...
    沈念sama閱讀 46,465評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡肺素,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了宇驾。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片倍靡。...
    茶點(diǎn)故事閱讀 40,675評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖课舍,靈堂內(nèi)的尸體忽然破棺而出塌西,到底是詐尸還是另有隱情,我是刑警寧澤筝尾,帶...
    沈念sama閱讀 36,354評(píng)論 5 351
  • 正文 年R本政府宣布捡需,位于F島的核電站,受9級(jí)特大地震影響筹淫,放射性物質(zhì)發(fā)生泄漏站辉。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評(píng)論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望饰剥。 院中可真熱鬧殊霞,春花似錦、人聲如沸汰蓉。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,514評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)顾孽。三九已至祝钢,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間若厚,已是汗流浹背拦英。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,616評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留盹沈,地道東北人龄章。 一個(gè)月前我還...
    沈念sama閱讀 49,091評(píng)論 3 378
  • 正文 我出身青樓吃谣,卻偏偏與公主長(zhǎng)得像乞封,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子岗憋,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評(píng)論 2 360

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

  • 基本思想 歸并排序(Merge-Sort) 是利用歸并的思想實(shí)現(xiàn)的排序的方法肃晚,該算法采用經(jīng)典的分治(divide-...
    謙卑王生閱讀 301評(píng)論 0 0
  • 一些概念 數(shù)據(jù)結(jié)構(gòu)就是研究數(shù)據(jù)的邏輯結(jié)構(gòu)和物理結(jié)構(gòu)以及它們之間相互關(guān)系,并對(duì)這種結(jié)構(gòu)定義相應(yīng)的運(yùn)算仔戈,而且確保經(jīng)過(guò)這...
    Winterfell_Z閱讀 5,854評(píng)論 0 13
  • 通過(guò)前面的知識(shí)关串,我們已經(jīng)知道,有序的數(shù)據(jù)在查找時(shí)有極大的性能提升监徘。很多查找都基于有序數(shù)據(jù)晋修,但并不是所有的結(jié)構(gòu)都能像...
    大大紙飛機(jī)閱讀 1,174評(píng)論 0 1
  • 一、 單項(xiàng)選擇題(共71題) 對(duì)n個(gè)元素的序列進(jìn)行冒泡排序時(shí)凰盔,最少的比較次數(shù)是( )墓卦。A. n ...
    貝影閱讀 9,097評(píng)論 0 10
  • 一切都在茫然中結(jié)束。美麗的憂(yōu)傷户敬,竟成了無(wú)言的結(jié)局落剪。 曾幾何時(shí),生命的意義對(duì)于我已艱澀難捱尿庐。那蘭色的夢(mèng)忠怖,在我的心靈深...
    秦時(shí)明月wk閱讀 1,679評(píng)論 40 67