js編寫四種基礎排序(冒泡排序、選擇排序、插入排序、快速排序)

講到算法,不可避免的會提到排序算法;在排序算法中,冒泡排序、選擇排序和插入排序等是最常被問到的幾種基本的排序算法。下面用js來實現這幾個簡單的排序。

1、冒泡排序

概念

從序列的最右邊開始比較相鄰兩個數字的大小,再根據結果交換兩個數字的位置,重複這一操作,實現所有數字從小到大或從大到小排列的算法即冒泡排序。

步驟

  1. 外層循環,n長的數組需要比較n趟,每次找到一個最小值
  2. 內層循環,每一趟之後需要比較的個數減1;
  3. 從序列的末尾開始比較相鄰兩個數字的大小;如果比較的數據比左邊相鄰的數據小,則左移當前比較的數據。
  4. 直至當前比較數據的位置等於當前比較次數時,則一輪結束。
  5. 比較完一輪後,繼續從末尾開始比較下一輪

代碼

// 編寫方法,實現冒泡
var arr = [29,45,29,72,51,68,72,97];
var getMaopao = function(arr) {
  //外層循環,控制趟數,每一次找到一個最小值
  for (var i =0; i< arr.length - 1; i++){
    // 內層循環,從右側開始控制比較的次數,並且判斷兩個數的大小
    for (var j = arr.length; j>= i; j--){
      // 如果後面的數小,放到前面(從小到大的冒泡排序)
      if (arr[j]< arr[j-1]) {
        var temp = arr [j];
        arr [j] = arr[j-1];
        arr[j-1] = temp;
      }
    }
  }
  return arr;
}
console.log('maopao', getMaopao(arr))

也可以是從前到後比較

for (var i = 0; i < arr.length - 1; i++) {
    // 內層循環,控制比較的次數,並且判斷兩個數的大小
    for (var j = 0; j < arr.length - 1 - i; j++) {
        if (arr[j] > arr[j + 1]) {
            var temp = arr[j];
            arr[j] = arr[j + 1];
            arr[j + 1] = temp;
        }
    }
}

2、選擇排序

概念

從待排序的數據中尋找最小值,將其與序列最左邊的數字進行交換,重複這一操作的算法即選擇排序。

步驟

  1. 循環數組,找到最小值
  2. 將最小值和最左邊的元素進行調換,完成第一輪
  3. 從第二位開始,循環數組,找到剩下的最小值
  4. 重複直到最後一輪,依次完成所有數據的排序

代碼

var arr = [120,29,45,29,72,51,68,72,97];
var getChoose = function(arr) {
  //外層循環,控制趟數,每一次找到一個最小值
  for (var i =0; i< arr.length - 1; i++){
    // 內層循環,從右側開始控制比較的次數,並且判斷兩個數的大小
    var min = arr[i];
    var minIndex = i;
    // 內層循環,每一次找到餘下數字的最小值,記錄下標
    for (var j = i; j< arr.length; j++){
      if (arr[j]<min) {
        min = arr[j]
        minIndex = j
      }
    }
    // 將最小值與第i位交換位置
    var temp = arr[i]
    arr[i] = arr [minIndex]
    arr[minIndex] = temp
  }
  return arr;
}
console.log('choose', getChoose(arr))

如果不記錄下標,在內層循環交換位置也是可以的(每次都把最小值往前交換,類似冒泡),但是這樣交換的次數會很多,運行速度會變慢。

3、插入排序

概念

從序列左端開始依次對數據進行排序的算法稱爲插入排序。(序列中數據分爲已排序區和未排序區,依次對每個數據和已排序區比較,進行排序)

步驟

  1. 假設第一個數字已完成排序,對第二個數字與第一個進行比較
  2. 如果小於它,則放到它之前,否則之後,完成排序
  3. 然後第三個數字,與前兩個已排序的進行比較,找到小於它的數字,放在此數字之後
  4. 如此反覆,完成整個數組的排序

代碼

// 編寫方法,實現插入排序
var arr = [120,29,45,29,72,51,68,72,97];
var getChoose = function(arr) {
  var newArr = [arr[0]];
  //外層循環舊數組,獲得未排序區的數字
  for (var i =1; i< arr.length; i++){
    // 內層循環新數組,將未排序區的數字與已排序區比較
    for (var j = 0; j< newArr.length; j++) {
      // 當數字小於已排序區的某個數字時,將此數字插入在已排序區的該數字之後,跳出循環
      if (arr[i]< newArr[j]) {
        newArr.splice(j,0,arr[i])
        break;
      }
    }
  }
  return newArr;
}
console.log('choose', getChoose(arr))

4、快速排序

概念

快速排序的原理,簡單來說就是把一個事情,分成很多小事情來處理,分治的思想。如找到一個基準,將大於它的放到右邊,小於它的所有數放到左邊,再分別對左右的數組重複此步驟,最後數組將按照從小到大的順序排列。

步驟

  1. 找基準(一般是以第一項爲基準)
  2. 遍歷數組,小於基準的放在left,大於基準的放在right
  3. 遞歸,對left和right內的數組不斷重複以上方式,直到最後剩下一位。(有些二分法的意思)

代碼

let dat=[5, 8, 10, 3, 2, 18, 17, 9];
var sortedData=function quickSort(data){
  //遞歸出口
    if(data.length<=1){
      return data;
  }
//此處要將基準數從原數組移除,避免上面的data.length判斷陷入死循環
  let  baseData=data.splice(0,1)[0];
  let  leftData=[],rightData=[];
//此處的data.length和上面不同,移除了基準數,比上面小1
   for(let i=0;i<data.length;i++){
      if(data[i]>baseData){
        rightData.push(data[i]);
      }else{
        leftData.push(data[i]);
      }
    }
    leftData=quickSort(leftData);
    rightData=quickSort(rightData);
    return   [...leftData, baseData, ...rightData];
  }
console.log(sortedData(dat));
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章