1. 程式人生 > 實用技巧 >js冒泡演算法以及優化

js冒泡演算法以及優化

氣泡排序是一種簡單的排序演算法。它重複地走訪過要排序的數列,一次比較兩個元素,如果它們的順序錯誤就把它們交換過來。走訪數列的工作是重複地進行直到沒有再需要交換,也就是說該數列已經排序完成。這個演算法的名字由來是因為越小的元素會經由交換慢慢“浮”到數列的頂端。

演算法描述

1、比較相鄰的元素。如果第一個比第二個大,就交換它們兩個;

2、對每一對相鄰元素作同樣的工作,從開始第一對到結尾的最後一對,這樣在最後的元素應該會是最大的數;

3、針對所有的元素重複以上的步驟,除了最後一個;

4、重複步驟1~3,直到排序完成;

動圖演示

程式碼實現

function randomArray(start,end){
  var a=[],o={},random,step=end-start;
	while(a.length<step){
	  random=start+parseInt(Math.random()*step);
	  if(!o["x"+random]){
	  a.push(random);
	  o["x"+random]=1;
	  };
	};
  return a;
};
let array = randomArray(1,100); //隨機獲取範圍為1-99的不重複數的陣列
console.log(array);
let sortArray = bubbleSort(array);
console.log(sortArray);
// 氣泡排序方法
function bubbleSort(array) {
  if (!Array.isArray(array)) {
    console.log("請傳入陣列");
    return false
  }
  for (let i = 0;i < array.length - 1;i++) {
    for (let j = 0;j < array.length - 1 - i;j++) {
      if (array[j] > array[j+1]) {
        let temp = array[j];
        array[j] = array[j+1];
        array[j+1] = temp;
      }
    }
  }
  return array;
}

 console的結果:

氣泡排序優化一

[2,1,3,4]在第一次迴圈後就變成[1,2,3,4],已經實現排序,但for迴圈仍會繼續。所以在交換迴圈中新增標記,如果某一次交換迴圈結束中都沒有發生交換事件,說明排序已經是OK的,此時應該跳出for迴圈。

程式碼實現

function bubbleSort1(array) {
  if (!Array.isArray(array)) {
    console.log("請傳入陣列");
    return false
  }
  for (let i = 0;i < array.length - 1;i++) {
    let sortDone = true;
    for (let j = 0;j < array.length - 1 - i;j++) {
      if (array[j] > array[j+1]) {
        let temp = array[j];
        array[j] = array[j+1];
        array[j+1] = temp;
        sortDone = false;
      }
    }
    if (sortDone) {
      break;
    }
  }
  return array;
}

氣泡排序優化二

假設陣列尾部幾個資料已經是有序排序的,比如[34,5,12,6,78,79,80,81,82],那後面幾個資料在交換迴圈中其實就可以不用去進行比較,直接查詢到交換的最後一個索引,並將該索引作為下次迴圈的終止點。

程式碼實現

function bubbleSort1(array) {
  if (!Array.isArray(array)) {
    console.log("請傳入陣列");
    return false
  }
  for (let i = 0;i < array.length - 1;i++) {
    let sortDone = true;
    let sortBorder = array.length - 1;
    let lastExchangeIndex = 0;     for (let j = 0;j < array.length - 1 - i;j++) {       if (array[j] > array[j+1]) {         let temp = array[j];         array[j] = array[j+1];         array[j+1] = temp;         sortDone = false;
        lastExchangeIndex = j;       }     }
    sortBorder = lastExchangeIndex;     if (sortDone) {       break;     }   }   return array; }
  

 最後我們來檢驗下這三種方法的迴圈次數。