JS冒泡排序的6種寫法(武當雄風)

天下英雄出我輩,一入江湖歲月催。鴻圖霸業談笑間,不勝人生一場醉。
武當山上,一年一度的試道大會又開始了...
衆武當弟子摩拳擦掌都想在這次試道大會上一展風采...
張三丰臨終前曾留下一句話:試道大會採用冒泡排序....
冒泡思想:每冒泡一輪(外層for循環控制),選出這一輪中最大的數(內層for循環依次兩兩比較逐步移到最後...)
一共進行arr.length-1輪 (2個比一輪、3個比兩輪、悟不出來本身收拾行李快快下山吧,我武當派沒有你這樣的弟子!)
每輪比較arr.length-1次?(由於每一輪冒泡獲得的最大值已經得道成仙無需再比 因此每輪比較arr.length-1-i次)node

靈魂版1(實力對決之一個都不能少)

由兩位德高望重的裁判主持
主裁判(外層for循環)負責輪數,副裁判(內層for循環)在主裁判的指導下負責每一場比武...
bubbleSortSoul1 = (arr = []) => {
        let count = 0;
        // i爲輪數(因i從0開始 即i<arr.length-1)
        for (let i = 0; i < arr.length - 1; i++) {
            count++;
            // 第i輪僅需比較length-1-i次
            for (let j = 0; j < arr.length - 1 - i; j++) {
                // 這裏能不能寫成arr[j-1]>arr[j]? 若是有這種特殊癖好 那麼j就從1開始吧,而後j<arr.length-i
                if (arr[j] > arr[j + 1]) {
                    let temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
        console.log(`bubbleSortSoul1排序完成用了${count}輪`);
        return arr;
    }

靈魂版2(實力對決之換湯不換藥)

副裁判突發奇想,竟悟出--心法,每輪比武再也不須要主裁判詳細指導(不用-i)
bubbleSortSoul2 = (arr = []) => {
        let length = arr.length - 1;
        let count = 0;
        for (let i = 0; i < arr.length - 1; i++) {
            count++;
            // 這裏的length第一輪==arr.length-1-0跟上一版同樣
            for (let j = 0; j < length; j++) {
                if (arr[j] > arr[j + 1]) {
                    let temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
            // 每一次內層for循環比較完成-1 跟前面的-i同樣 換湯不換藥
            length--;
        }
        console.log(`bubbleSortSoul2排序完成用了${count}輪`);
        return arr;
    }

靈魂版3(實力對決之副裁判獨擔重任)

主裁判臨時有事請假,大會當頭,副裁判迫於壓力終悟出冒泡心經,大會依然有序進行...
bubbleSortSoul3 = (arr = []) => {
        let length = arr.length - 1;
        let count = 0;
        // 單層for循環
        for (let j = 0; j < length; j++) {
            if (arr[j] > arr[j + 1]) {
                let temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
            // 在循環到最大值時候重置j(j=-1到上面j++重置爲0)這樣能夠省了外層for循環
            // 某弟子問:兄dei 這樣也行?靠譜不?師傅知道你在瞎搞不?
            // 副裁判:好比如武別廢話!冒泡心經!汝輩豈知?
            if (j == length - 1) {
                j = -1;
                length--;
                count++;
            }
        }
        console.log(`bubbleSortSoul3排序完成用了${count}輪`);
        return arr;
    }

沒有靈魂版1(flag心法?比武可能提早結束)

師父得知副裁判在主裁判不在的狀況下成功舉行了一場大會,頗爲高興,決定傳一套flag心法給副裁判
這次大會由主裁判弟弟while擔任,弟弟畢竟是弟弟,知道的太少了,只能遵從安排
副裁判對弟弟說:這樣吧,等會比武我微信給你發true你就喊開始,發false你就喊結束,are you OK? 弟弟表示很OK
內幕:部分弟子比武期間被安排得明明白白?比武提早結束...
bubbleSortNoSoul1 = (arr = []) => {
        let [length, flag, count] = [arr.length - 1, true, 0];
        // 這裏用while執行輪數 (也能夠用for)
        while (flag) {
            count++;
            // flag心法第一章:他強由他強 清風拂山崗 他橫由他橫 明月照大江
            // 副裁判準備立刻微信給弟弟發false想要結束比武 剛打好沒發出去 下面的弟子開始躁動了 幹哈呢 比不比了??
            // 好在副裁判有慧根 當即悟出原理(這次比完沒有交換就結束吧 再比也沒有意義了!)師父果真是師父!佩服!
            flag = false;
            // 你們安靜 仍是老規矩 繼續...
            for (let j = 0; j < length; j++) {
                if (arr[j] > arr[j + 1]) {
                    let temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                    // 若是這次循環有交換 則說明還得再來一輪,繼續往下比...這輪結束就發true給弟弟
                    flag = true;
                }
            }
            length--;
        }
        console.log(`bubbleSortNoSoul1排序完成用了${count}輪`);
        return arr;
    }

沒有靈魂版2(左右互博之術?副裁判獲得周伯通真傳)

while弟弟被逼作數學題,比大小
副裁判備受周伯通喜歡,習得左右互博之術,並將之發揚光大...
bubbleSortNoSoul2 = (arr = []) => {
        let [j, temp, left, right, count] = [0, 0, 0, arr.length - 1, 0];
        while (left < right) {
            count++;
            for (j = left; j < right; j++) {
                if (arr[j] > arr[j + 1]) {
                    temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
            right--;
            for (j = right; j > left; j--) {
                if (arr[j - 1] > arr[j]) {
                    temp = arr[j];
                    arr[j] = arr[j - 1];
                    arr[j - 1] = temp;
                }
            }
            left++;
        }
        console.log(`bubbleSortNoSoul2排序完成用了${count}輪`);
        return arr;
    }

沒有靈魂版3(flag心法+左右互博)

這場比武讓副裁判終成一代大俠...
bubbleSortNoSoul3 = (arr = []) => {
        let [j, temp, left, right, flag, count] = [0, 0, 0, arr.length - 1, true, 0];
        while (left < right && flag) {
            count++;
            flag = false;
            for (j = left; j < right; j++) {
                if (arr[j] > arr[j + 1]) {
                    temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                    flag = true;
                }
            }
            right--;
            for (j = right; j > left; j--) {
                if (arr[j - 1] > arr[j]) {
                    temp = arr[j];
                    arr[j] = arr[j - 1];
                    arr[j - 1] = temp;
                    flag = true;
                }
            }
            left++;
        }
        console.log(`bubbleSortNoSoul3排序完成用了${count}輪`);
        return arr;
    }

測試結果:微信

let arr1 = [1, 2, 7, 8, 4, 5, 6, 3, 9];

    console.time('1');
    console.log(bubbleSortSoul1(arr1.concat()));  //8輪
    console.timeEnd('1');
    console.time('2');
    console.log(bubbleSortSoul2(arr1.concat()));  //8輪
    console.timeEnd('2');
    console.time('3');
    console.log(bubbleSortSoul3(arr1.concat()));  //8輪
    console.timeEnd('3');
    console.time('4');
    console.log(bubbleSortNoSoul1(arr1.concat()));//6輪
    console.timeEnd('4');
    console.time('5');
    console.log(bubbleSortNoSoul2(arr1.concat()));//4輪
    console.timeEnd('5');
    console.time('6');
    console.log(bubbleSortNoSoul3(arr1.concat()));//3輪
    console.timeEnd('6');

node環境下測試結果

注:

  • 汝輩豈知。——《三國演義》孔明空城計,司馬懿兩個兒子要攻城,司馬懿:汝輩豈知?宜速退。
  • 他強由他強 清風拂山崗 他橫由他橫 明月照大江。——出自金庸《倚天屠龍記》裏九陽真經。
  • 周伯通。——金庸《射鵰英雄傳》人物,曾將空明拳和雙手互博之術傳給郭靖。
相關文章
相關標籤/搜索