JavaScript数据结构与算法(排序算法)

49次阅读
没有评论

共计 3648 个字符,预计需要花费 10 分钟才能阅读完成。

冒泡排序

在所有排序算法中最简单,然而,从运行时间的角度看,冒泡排序是最差的一个。

function swap(array, a, b) {const temp = array[a]
  array[a] = array[b]
  array[b] = temp
}

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

  console.log(array)
}

bubbleSort([1, 3, 5, 2, 0])

选择排序

一种原址比较排序算法。选择排序大致思路是找到数据结构中的最小值并将其放置在第一位,接着找到第二小的值并将其放在第二位,以此类推。

function selectionSort(arr) {const { length} = arr
  let indexMin
  for (let i = 0; i < length - 1; i++) {
    indexMin = i
    for (let j = i; j < length; j++) {if (arr[indexMin] > arr[j]) {indexMin = j}
    }
    if (i !== indexMin) {swap(arr, i, indexMin)
    }
  }

  console.log(arr)
}

selectionSort([1, 3, 5, 2, 0])

插入排序

function insertionSort(array) {const { length} = array
  let temp
  for (let i = 1; i < length; i++) {
    let j = i
    temp = array[i]
    while (j > 0 && array[j - 1] > temp) {array[j] = array[j - 1]
      j--
    }
    array[j] = temp
  }

  console.log(array)
}

insertionSort([1, 3, 5, 2, 0])

归并排序

第一个可以实际使用的排序算法。前三个排序算法性能不好,但归并排序性能不错,其复杂度为 O(nlog(n))。

归并排序是一种分而治之算法。其思想是将原始数组切分成较小的数组,直到每个小数组只有一个位置,接着将小数组归并成较大的数组,直到最后只有一个排序完毕的大数组。

function mergeSort(array) {if (array.length > 1) {const { length} = array
    const middle = Math.floor(length / 2)
    const left = mergeSort(array.slice(0, middle))
    const right = mergeSort(array.slice(middle, length))
    array = merge(left, right)
  }

  return array
}

function merge(left, right) {
  let i = 0
  let j = 0
  const result = []
  while (i < left.length && j < right.length) {result.push(left[i] < right[j] ? left[i++] : right[j++])
  }
  return result.concat(i < left.length ? left.slice(i) : right.slice(j))
}

console.log(mergeSort([1, 3, 5, 2, 0]))

快速排序

也许是最常用的排序算法了。它的复杂度为 O(nlog(n)),且性能通常比其他复杂度为 O(nlog(n)) 的排序算法要好。和归并排序一样,快速排序也使用分而治之的方法,将原始数组分为较小的数组(但它没有像归并排序那样将它们分割开)。

function quickSort(arr) {const { length} = arr
  if (length < 2) {return arr}

  let base = arr[0]
  let minArr = arr.slice(1).filter((item) => item <= base)
  let maxArr = arr.slice(1).filter((item) => item > base)

  return quickSort(minArr).concat(base).concat(quickSort(maxArr))
}

console.log(quickSort([1, 3, 5, 2, 0]))

计数排序

是分布式排序。

function countSort(arr) {if (arr.length < 2) {return arr}

  const maxValue = findMax(arr)
  const counts = new Array(maxValue + 1)
  arr.forEach((item) => {if (!counts[item]) {counts[item] = 0
    }
    counts[item]++
  })

  let sortIndex = 0
  counts.forEach((count, index) => {while (count > 0) {arr[sortIndex++] = index
      count--
    }
  })

  return arr
}

function findMax(arr) {let max = arr[0]
  for (let i = 1; i < arr.length; i++) {if (arr[i] > max) {max = arr[i]
    }
  }
  return max
}

console.log(countSort([1, 3, 5, 2, 0]))

桶排序

也被称为箱排序,是分布式排序算法。它将元素分为不同的桶(较小的数组),再使用一个简单的排序算法,例如插入排序(用来排序小数组不错的算法),来对每个桶进行排序。然后,它将所有的桶合并为结果数组。

function bucketSort(array, bucketSize = 3) {if (array.length < 2) {return array}
  const buckets = createBucket(array, bucketSize)
  return sortBucket(buckets)
}

function createBucket(array, bucketSize) {let minValue = array[0]
  let maxValue = array[0]
  for (let i = 1; i < array.length; i++) {if (array[i] < minValue) {minValue = array[i]
    } else if (array[i] > maxValue) {maxValue = array[i]
    }
  }

  const bucketCount = Math.floor((maxValue - minValue) / bucketSize) + 1
  const buckets = []
  for (let i = 0; i < bucketCount; i++) {buckets[i] = []}

  for (let i = 0; i < array.length; i++) {const bucketIndex = Math.floor((array[i] - minValue) / bucketSize)
    buckets[bucketIndex].push(array[i])
  }

  return buckets
}

function sortBucket(buckets) {const sortedArray = []
  for (let i = 0; i < buckets.length; i++) {if (buckets[i] != null) {insertionSort(buckets[i])
      sortedArray.push(...buckets[i])
    }
  }
  return sortedArray
}

function insertionSort(array) {const { length} = array
  let temp
  for (let i = 1; i < length; i++) {
    let j = i
    temp = array[i]
    while (j > 0 && array[j - 1] > temp) {array[j] = array[j - 1]
      j--
    }
    array[j] = temp
  }
}

console.log(bucketSort([1, 3, 5, 2, 0]))

基数排序

也是一个分布式排序算法,它根据数字的有效位或基数(这也是它为什么叫基数排序)将整数分布到桶中。基数是基于数组中值的记数制的。

function radixSort(arr) {
  const base = 10
  let divider = 1

  const maxValue = Math.max(...arr)
  while (divider <= maxValue) {const buckets = [...Array(10)].map(() => [])
    for (let i of arr) {buckets[Math.floor(i / divider) % base].push(i)
    }

    arr = [].concat(...buckets)
    divider *= base
  }

  return arr
}

console.log(radixSort([1, 3, 5, 2, 0]))

正文完
post-qrcode
 0
三毛
版权声明:本站原创文章,由 三毛 于2023-08-31发表,共计3648字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)