01 【JS排序算法】JavaScript實現冒泡排序

寫在前面

本文是學習"ben大叔"大佬的相關文章所總結而成。

作爲一名前端,你可以不瞭解複雜的一些算法實現,但是關於排序算法你可要了解和掌握哦,比如以下這幾種:

 

冒泡排序簡介

冒泡排序作爲排序算法家族中的成員來說,相當於編程語言學習中的"Hello World",因爲它是最簡單的排序算法。冒泡排序會重複走訪待排序序列,每次會比較序列中的相鄰兩個元素,如果這兩個元素的順序錯誤,就將它倆位置互換,依次重複進行此操作,直到待排序序列中沒有要進行交換的操作爲止,就意味着已經完成了排序。由於冒泡排序中每次重複比較兩個元素、交換位置的過程中,值較小的數據往往會被排到數列的前面,值越大的數據會往後排,這就像是水裏的水泡一樣往上冒,所以它的名字由此而來。

 

冒泡排序實現過程

  1. 比較相鄰的兩個元素,如果第一個比第二個大,就交換它們位置;
  2. 對待排序序列中的每一對相鄰元素做上面重複操作,從最開始的一對到最後的一對,這樣每次一輪比較結束後,結尾的元素是最大的數;
  3. 重複以上兩個步驟,直到排序完成。

 

冒泡排序的動圖演示

 

冒泡排序代碼實現


        function bubbleSort(arr) {
            var len = arr.length;
            for(var i = 0; i < len - 1; i++) {
                for(var j = 0; j < len - 1 - i; j++) {
                    if(arr[j + 1] < arr[j]) {
                        var middle = arr[j+1];
                        arr[j+1] = arr[j];
                        arr[j] = middle;
                    }
                }
            }
            return arr;
        };

        var defaultArr = [3, 5, 32, 15, 7, 26, 10, 55, 45, 12, 28, 88, 18];     //待排序序列
        var resultArr = bubbleSort(defaultArr);
        console.table(resultArr);

可以通過上面代碼看到,冒泡排序的實現原理就是雙重循環,如果後一個數小於前一個數,就替換它們的位置,這樣重複進行直至循環結束。它每次比較時都將數值較大的數據放在結尾,所以將我們的數組實際上是從小到大進行了排序,同理,要想實現從大到小排序,我們只需要將條件判斷語句中的小於號改成大於號即可。

 

冒泡排序應用場景

  • 比較適用於小數據量的排序(從小到大或者從大到小),因爲原理簡單,並且數據量大的話循環次數極多,降低性能;
  • 適用於教學,因爲原理簡單。

 

冒泡排序的算法口訣

  • 外層循環從0到N-1;     (控制比較的輪數,N爲元素個數)
  • 內層循環從0到N-1-i;    (控制每一輪比較次數)
  • 兩兩比較作交換。

 

冒泡排序的優化

我們上述實現的僅僅是冒泡排序的基礎版,也就是實現了一個能用的冒泡排序算法而已,如果數據量較大的話,它的性能是極低的,所以接下來我們優化一下(雖然並沒有實質性的作用,但還是介紹下)。

冒泡排序的優化大家記住一點即可:冒泡排序優化其實就是減少比較次數,本質上不會有較大的性能提升。

1、添加flag的方式


        //flag版優化
        function bubbleSort_flag(arr) {
            var len = arr.length;
            var flag = false;     //添加一個flag,用於標識原序列是否是一個有序序列

            if(len <= 1) {     //如果僅僅有一個元素直接返回
                return arr;
            }

            for(var i = 0; i < len - 1; i++) {
                for(var j = 0; j < len - 1 - i; j++) {
                    if(arr[j + 1] < arr[j]) {
                        var middle = arr[j+1];
                        arr[j+1] = arr[j];
                        arr[j] = middle;
                        flag = true;
                    }
                }

                if(!flag) break;    //如果一次都沒有發生數據交換就返回原序列,因爲已經是一個有序序列
            }
            return arr;
        }

        var defaultArr = [3, 5, 32, 15, 7, 26, 10, 55, 45, 12, 28, 88, 18];
        var resultArr = bubbleSort_flag(defaultArr);
        console.table(resultArr);

2、雙向冒泡排序(雞尾酒排序)

基礎版的冒泡排序是從一端開始,依次循環比較相鄰元素實現的,爲了減少比較次數,略微的提高一下性能,我們可以選擇讓排序從兩頭開始,即遵循"較大氣泡從左往右移動,較小氣泡從右往左移動"的方式來實現,如下:


        //雙向冒泡排序
        function bubbleSort_twoway(arr) {
            var len = arr.length;    //依次將最大的數放置到數組末尾,將第二大的數放到倒數第二位...
            var flag = false;
            for(var i = 0; i < len/2; i++) {
                flag = false;
                for(var j = i; j < len - 1 - i; j++) {   //從前往後,比較相鄰兩個數,把大的放在後邊.之前已放置成功的可以不再參與比較
                    if(arr[j] > arr[j + 1]) {
                        var middle = arr[j];
                        arr[j] = arr[j+1];
                        arr[j+1] = middle;
                        flag =true;
                    }
                }
                if(!flag){
                    break;
                }

                for(var j = len - 1 - i; j > i; j--){
                    if(arr[j] < arr[j - 1]) {
                        var middle = arr[j];
                        arr[j] = arr[j-1];
                        arr[j-1] = middle;
                        flag = true;
                    }
                }
                if(!flag){
                    break;
                }
            }
            return arr;
        }

        var defaultArr = [3, 5, 32, 15, 7, 26, 10, 55, 45, 12, 28, 88, 18];
        var resultArr = bubbleSort_twoway(defaultArr);
        console.table(resultArr);

 

冒泡排序優缺點:

  • 優點:簡單、空間複雜度低、穩定
  • 缺點:時間複雜度高、效率低
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章