冒泡排序(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 }ishi 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的判斷。通過這種改進,可以避免在有序的情況下進行無意義的循環判斷。
看完大話數據結構,根據自己的理解整理了下,還請大家留下寶貴意見。
冒泡排序(js版)