1. 程式人生 > >讓冒泡排序的對比次數更少(js實例)

讓冒泡排序的對比次數更少(js實例)

[1] div 必須 數組元素 add 利用 fin dex 整理

一般網上的冒泡排序例子是這樣的:

function bubbleSort(arr) {
  let i = arr.length;
    let tempExchangVal = undefined;
    while (i > 0) {
        for (let j = 0; j < i - 1; j++) {
       num++;
            if (arr[j] > arr[j + 1]) {
                tempExchangVal = arr[j];
                arr[j] = arr[j + 1];
                arr[j 
+ 1] = tempExchangVal; } } i--; } return arr; } let arr = [3, 2, 4, 9, 5, 7, 1, 6, 8]; let num = 0; // 對比的次數變量 let arrSorted = bubbleSort(arr); console.log(arrSorted); // [1, 2, 3, 4, 5, 6, 7, 8, 9] console.log(num); // 36

思路就是一個數組裏有幾個數字就循環幾次取出索引來利用(為了稱呼方便,稱此次循環叫做大循環),然後將被取出的循環數字再帶入數組循環一遍找出當前循環裏最大的數(為了稱呼方便,稱此次循環叫做小循環),最大的數將被移到數組最尾部,並且使得在這過程中的數字位置能夠調整規範。小循環後再將 i

變量減一,用來進行下一個大循環並且使小循環不會循環到之前已經移到數組最尾部的數字。

但這種寫法有個弊端就是如果上次循環已經對比整理了前後數組,這次循環還會再進行對比,不過不會再整理,這樣算是多做了無用功。舉個例子:上次循環已經把最前面的3個數字3、2、4對比排列成了2、3、4,這次循環依然還會再對比一次2和3跟3和4。這其實是可以不用對比的,因為之前已經對比排列過了,再對比一次只能算是多此一舉,像上面這種,已經對比了36次,其中有很大一部分是重復的對比。

後來,我自己想出了另一種對比更少的算法:

let oldArr = [3, 2, 4, 9, 5, 7, 1, 6, 8]
let num 
= 0 // 對比次數的變量 function bubbleSort (arr, index = 0) { let indexAdd1 = index + 1 for (let i = 0; indexAdd1 > 0; indexAdd1--) { let compareArr = [arr[indexAdd1 - 1], arr[indexAdd1]] num++ if (compareArr[0] > compareArr[1]) { arr[indexAdd1 - 1] = compareArr[1] arr[indexAdd1] = compareArr[0] } else { break } } if (index < arr.length - 1) { return bubbleSort(arr, index + 1) } else { return arr } } let sortArr = bubbleSort(oldArr) console.log(sortArr) // [1, 2, 3, 4, 5, 6, 7, 8, 9] console.log(num) // 19

我自己的思路是這樣:循環一遍所有索引(大循環),每次循環執行函數時都會把上次循環處理過的數組帶入進去,直到最後一個索引將最後處理的數組返回回去,每次進行大循環時,都會將要循環處理的索引和它的下一位比較,如果下一位比處理的索引大那就沒問題,不進行操作,如果比它小就和其調換,然後再往後面進行對比調換,直到遇到一個比它還小的數才停止對比調換(小循環)。

例如:索引[0]是3,它的下一位是2,3比2大所以調換位置,調換後2後面沒有索引了,所以沒有再執行對比調換;由於上個循環有調換索引了,現在索引[1]還是3,它的下一位索引[2]是4,3比4小索引不調換;接著索引[2]是4,下一位索引[3]是9,4比9小所以也沒調換位置;索引[3]是9,下一個索引[4]是5,9比5大那就必須調換位置了,現在索引[3]是5而索引[4]是9了,然後再將索引[3]和後面的索引對比,現在對比索引[2],索引[2]是4,比5小,所以無需再調換,因為之前已經按大小排序了,所以索引[2]後面的數肯定比索引[2]小,那也就無需再對比了,這樣就可以節省幾步了,而這幾步也是第一個寫法時重復的步驟;接著再從索引[4]開始對比,對比索引[5],然後按照結果看是要移動位置還是不用;索引[5]再對比索引[6],索引[6]再對比索引[7]。。。直到最後一位索引索引。

兩種寫法如果數組元素較少對比的次數可能不會差多少,不過如果數組元素比較多第一種算法就會進行很多重復的比較了。

讓冒泡排序的對比次數更少(js實例)