js氣泡排序動畫

鄭明遠發表於2019-03-04

在《深入淺出node》中看到了這個問題,感覺很有趣,那就寫一個吧!效果如圖:

js氣泡排序動畫

我們先來實現一個簡單的氣泡排序:

const arrLength = 10
const arrRange = 30

const generateArr = () => {
  return Array.from({ length: arrLength }).map(() =>
    Math.floor(Math.random() * arrRange)
  )
}

const compare = (x, y) => x - y

const swap = (a, i, j) => {
  a[i] ^= a[j]
  a[j] ^= a[i]
  a[i] ^= a[j]
}

const bubbleSort = a => {
  const len = a.length
  for (let i = 0; i < len; i++) {
    for (let j = 0; j < len - i - 1; j++) {
      if (compare(a[j], a[j + 1]) > 0) {
        swap(a, j, j + 1)
      }
    }
  }
}

const arr = generateArr()
console.log(arr)

bubbleSort(arr)
console.log(arr)
複製程式碼

接下來實現一個圖表:

const generateChart = () => {
  const block = document.querySelector('#sort')
  block.style.width = `${arrLength * (pillarGap + pillarWidth)}px`
  for (let i = 0; i < arrLength; i++) {
    const newDiv = document.createElement('div')
    Object.assign(newDiv.style, {
      height: `${((arr[i] / arrRange) * 100).toFixed(0)}%`,
      width: `${pillarWidth}px`,
      marginLeft: `${pillarGap}px`
    })
    newDiv.innerText = arr[i]
    block.append(newDiv)
  }
}
複製程式碼

排序中主要變化是交換,再寫一個交換元素的函式:

function exchange(el1, el2) {
  var ep1 = el1.parentNode,
    ep2 = el2.parentNode,
    index1 = Array.prototype.indexOf.call(ep1.children, el1),
    index2 = Array.prototype.indexOf.call(ep2.children, el2)
  ep2.insertBefore(el1, ep2.children[index2])
  ep1.insertBefore(el2, ep1.children[index1])
}
複製程式碼

最後我們只要把 bubbleSort 變為非同步呼叫即可:

const bubbleSort = async a => {
  const len = a.length
  for (let i = 0; i < len; i++) {
    for (let j = 0; j < len - i - 1; j++) {
      await swapTransform(a, j, j + 1, compare(a[j], a[j + 1]) > 0)
    }
  }
  return a
}
複製程式碼

全部程式碼在我的GitHub上: github.com/wen98y/work… 歡迎 Star

這個花了2個多小時寫完的,還是有些收穫:

  1. 多關注js原生操作DOM
  2. async 的運用
  3. css運算子優先順序

也有不足之處:這裡交換很生硬,沒有漸變的動畫,我想的是用transform來寫,但最後還是沒想出來,如果各位有高招,歡迎評論。

還有用原生js擼程式碼是真的爽!

相關文章