冒泡排序(js版)


基本思想兩兩比較相鄰記錄的關鍵字,如果反序則交換,直至沒有反序為止。

  • 最初的冒泡排序(初級版)
 1 //從小到大
 2 function BubbleSort(arr){
 3     var i,j,temp;
 4     for(i=0;i<arr.length-1;i++){
 5         for(j=i+1;j<arr.length;j++){
 6             if(arr[i]>arr[j]){
 7                 temp=arr[j];
 8                 arr[j]=arr[i];
 9                 arr[i]=temp;
10             }
11         }
12     }
13     return arr;
14 }
15 var arr=[10,7,9,11,22,33,4,2,0,1000];
16 BubbleSort(arr);  
17 console.log(arr); //[0, 2, 4, 7, 9, 10, 11, 22, 33, 1000]

由於這樣的排序僅僅是交換順序,不算是真正的冒泡排序,效率也比較低。

當i=0,

arr[0]和它后邊的每一項進行比較大小,前者大於后者,則進行交換。始終保證arr[0]為最小值。

當i=1,(arr[0]已經為最小值,不需要進行比較,)

arr[1]和它后邊的每一項進行比較大小,前者大於后者,則進行交換。始終保證arr[1]為最小值(除去arr[0]以外)。

.......直至i=arr.length-2時,保證前arr.length-1項均“比較”小(小於后邊的所有項),此時不再需要進行比較。(當n個數,前n-1個為“比較”小的值后,最后一個還有什么比較的意義呢??)

  • 正宗的冒泡排序(將小的數字如同氣泡一樣慢慢的浮上表面)

 

 1     //從小到大
 2     function BubbleSort(arr){
 3         var i,j,temp;
 4         for(i=0;i<arr.length-1;i++){
 5             for(j=arr.length-1;j>i;j--){
 6                 if(arr[j]<arr[j-1]){ //j為從后往前循環
 7                     temp=arr[j-1];
 8                     arr[j-1]=arr[j];
 9                     arr[j]=temp;
10                 }
11             }
12         }
13         return arr;
14     }
15     var arr=[10,7,9,11,22,33,4,2,0,1000];
16     BubbleSort(arr);

17 console.log(arr);// [0, 2, 4, 7, 9, 10, 11, 22, 33, 1000]

 當i=0時,

j的第1次循環:j=arr.length-1,j從數組的最后一項開始和前一項比較大小,當前者小於后者,交換位置。

j的第2次循環:j=arr.length-2,繼續和前一項比較大小。

......直至j=1時結束。此時數組的第一項為最小值。

當i=2時,

j的第1次循環:j=arr.length-1,j從數組的最后一項開始和前一項比較大小,當前者小於后者,交換位置。

j的第2次循環:j=arr.length-2,繼續和前一項比較大小。

......直至j=2時結束(即比較完第三項和第二項,第一項已經確定,不需要進行比較)。此時數組的第二項為最小值(除去第一項以外)。

繼續循環i,i=arr.length-2時。比較j的第arr.length項和第i=arr.length-1項,即可得到最終結果。

  •  優化后的冒泡排序

當待排序的序列為{2,1,3,4,5,6,7,8,9},那么僅僅需要交換第一個和第二個關鍵字即可。但是前面的算法還是會將循環都執行一遍,造成了多余的計算。

此時我們可以添加一個標記變量flag。

 1 //從小到大
 2 function BubbleSort(arr){
 3     var i,j,temp;
 4     var flag=true;     //flag進行標記
 5     for(i=0;i<arr.length-1&&flag;i++){  //若flag為false則退出循環
 6         flag=false;    //初始化為false
 7         for(j=arr.length-1;j>i;j--){
 8             if(arr[j]<arr[j-1]){ //j為從前往后循環
 9                 temp=arr[j-1];
10                 arr[j-1]=arr[j];
11                 arr[j]=temp;
12                 flag=true; //如果有數據交換則為true
13             }
14         }
15     }
16     return arr;
17 }
18 var arr=[10,7,9,11,22,33,4,2,0,1000];
19 BubbleSort(arr); 20 console.log(arr); // [0, 2, 4, 7, 9, 10, 11, 22, 33, 1000]

標記變量聲明時狀態為true,進行循環后,標記變量初始化為false狀態。當后邊的項兩兩進行比較時,發生交換則將標記變量狀態更正為true,如果自始至終標記變量的狀態都沒有更正為true,說明為有序,則在外層循環的終止判斷語句中退出。

優化的關鍵在於:

在變量i的for循環中,增加了對flag是否為true的判斷。通過這種改進,可以避免在有序的情況下進行無意義的循環判斷。

  • 時間復雜度

1.最好的情況,即數組有序,可以推斷出就是n-1次的比較,時間復雜度為O(n) 
2.當最壞的情況,即數組逆序,第一個數需要排n-1次,第二個數需要排n-2次,第3個數需要排n-3次……這樣依次類推,最后一個數只需要排一次,加起來共需要排n(n-1)/2次,所以時間復雜度為O(O^2)

看完大話數據結構,根據自己的理解整理了下,還請大家留下寶貴意見。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM