1. 程式人生 > 實用技巧 >break、 continue、 while、Do....while。

break、 continue、 while、Do....while。

氣泡排序

比較所有相鄰的兩項,如果第一個比第二個大,則交換他們

最好O(n) 最壞O(n^2) 平均O(n^2) 穩定

function bubbleSort(array) {
  const length = array.length
  // 外層迴圈控制比較的輪數
  for (let i = 0; i < length; i++) {
    // 裡層迴圈控制每一輪比較的次數
    // 使用 length - 1 - i 是為了減去外層迴圈已經排序過的趟數,優化次數
    for (let j = 0; j < length - 1 - i; j++) {
      if (array[j] > array[j + 1]) {
        let temp = array[j]
        arr[j] = arr[j + 1]
        arr[j + 1] = temp
      }
    }
  }
  return array
}
let arr = [1, 5, 3, 2, 4]
console.log(bubbleSort(arr))
// [1, 2, 3, 4, 5]

插入排序

假設第一項已經排序了,接著和第二項進行比較,取出第二項的索引和值,判斷第二項應該待在原位還是插到第一項之前?這樣,頭兩項就已經正確排序,接著已經排序好的再和第三項比較(它應該插入到第一、第二、還是原位置?),以此類推

最好O(n) 最壞O(n^2) 平均O(n^2) 穩定

function insertionSort(arr) {
  const length = arr.length
  // 假設索引0已經排序,所以從索引1開始遍歷
  for (let i = 1; i < length; i++) {
    let j = i
    let temp = arr[i]
    // 迴圈遍歷前一項
    while (arr[j - 1] > temp && j > 0) {
      // 將前一項後移
      arr[j] = arr[j - 1]
      j--
    }
    // 次數 j 既為需要插入的索引
    arr[j] = temp
  }
  return arr
}
let arr = [1, 5, 3, 2, 4]
console.log(insertionSort(arr))
// [1, 2, 3, 4, 5]

模擬換牌

function insertionSort(arr) {
  // 1.準備一個新陣列,用來儲存抓到手裡的牌,開始先抓一張牌進來
  let handle = []
  handle.push(arr[0])

  // 2.從第二項開始依次抓牌,一直把檯面上的牌抓光
  for (let i = 1; i < arr.length; i++) {
    // A 是新抓的牌
    let A = arr[i]
    // 和 HANDLE 手裡的牌依次比較(從後向前比)
    for (let j = handle.length - 1; j >= 0; j--) {
      // 沒一次要比較的手裡的牌
      let B = handle[j]
      // 如果當前的新牌 A 比要比較的牌 B 大,就把 A 放到 B 的後面
      if (A > B) {
        handle.splice(j + 1, 0, A)
        break
      }
      // 已經比到第一項,我們把新牌放到手中最前面即可
      if (j === 0) {
        handle.unshift(A)
      }
    }
  }
  return handle
}
let arr = [1, 5, 3, 2, 4]
console.log(insertionSort(arr))
// [1, 2, 3, 4, 5]

快速排序

分而治之思想

  • 選擇基準值,一般是將開頭、中間、末尾三個數先進行排序,中間值作為基準值

  • 將陣列分為左右兩個子陣列:小於基準值得元素組成的子陣列和大於基準值得元素組成的子陣列

  • 對這兩個子陣列進行快速排序(遞迴)

最好O(nlog^n) 最壞O(n^2) 平均O(nlog^n) 不穩定

function quickSort(arr) {
  // 4.結束遞迴,(當 arr 中小於等於一項,則不用處理)
  if (arr.length <= 1) {
    return arr
  }
  // 1.找到陣列的中間值,在原有的陣列中把它移除
  let minddleIndex = Math.floor(arr.length / 2)
  let minddleValue = arr.splice(minddleIndex, 1)[0]
  // 2.準備左右兩個陣列,迴圈剩下陣列中的每一項,
  // 比當前項小的放到左邊陣列中,反之放到右邊陣列中
  let arrLeft = []
  let arrRight = []
  for (let i = 0; i < arr.length; i++) {
    let current = arr[i]
    current < minddleValue ? arrLeft.push(current) : arrRight.push(current)
  }
  // 3.遞迴方式讓左右兩邊的陣列持續這樣處理,一直到左右兩邊都排好序為止
  // 最後讓左邊+中間+右邊拼接為最後的結果
  return quickSort(arrLeft).concat(minddleValue, quickSort(arrRight))
}
let arr = [1, 5, 3, 2, 4]
console.log(quickSort(arr))
// [1, 2, 3, 4, 5]