image.png
image.png
image.png
image.png

image.png

image.png

image.png

lgn! lgn阶乘 <= nlgn

推导公式如下
image.png

image.png

image.png

image.png

快速排序

image.png

image.png
image.png

  1. // 快速排序
  2. function swap (A, i, j) {
  3. [A[i], A[j]] = [A[j], A[i]]
  4. }
  5. function partition (A, lo, hi) { // A数组 lo起始位置 hi结束位置
  6. let pivot = A[hi - 1]
  7. let i = lo, j = hi - 1
  8. // 小于中心的范围 [lo,pivot)
  9. // 大于中心得范围 [j,hi-1)
  10. // 结束条件 i==j
  11. // 未确定范围[i,j)
  12. while (i !== j) {
  13. if (A[i] <= pivot) {
  14. i++
  15. } else {
  16. swap(A, i, --j)
  17. }
  18. }
  19. // 最后结束后,还有中心点进行交换
  20. swap(A, j, hi - 1)
  21. return j
  22. }
  23. function qsort (A, lo = 1, hi = A.length) {
  24. if (hi - lo <= 1) return
  25. const p = partition(A, lo, hi)
  26. qsort(A, lo, p)
  27. qsort(A, p + 1, hi)
  28. }
  29. const C = [10,50,30,90,40,80,70]
  30. qsort(C)
  31. console.log(C);

image.png

记数排序

时间复杂度 O(n)
空间复杂度 O(n)
image.png
1.循环遍历一下数组A
2.找出原数组A得最大值然后把他+1
3.创造一个 比最大值 多1 得长度得数组
4.然后遍历出每一项出现得次数,让他得对应下标++
image.png
5.累计数组B从左到右用自己 当前值,加前一个位置得数 ,比如现在i=5 所在得位置就应该是 5+1 = 6
image.png
6.在往回填值得时候,就需要在 原数组中取值,然后在累计数组中找到对应得位置,如图i=6,得时候 6得位置原来是7,7-1得位置就应该是 6 要放入得位置,然后5 也是5这里是 6 ,6-1 也就放到 5 得位置
7.下图中 3 得位置原来是 5 ,5-1 要放入 4 得位置,然后要让 累计数组中的位置— ,防止接下来还有3,遍历得时候接下来,确实有个3 ,3就放在4-1点得位置就是 3
8.继续循环直到结束

image.png
image.png

  1. // 计数排序
  2. function counting_sort (A) {
  3. const max = Math.max(...A)
  4. //累计数组
  5. const B = Array(max + 1).fill(0)
  6. //结果数组
  7. const C = Array(A.length)
  8. // 累计位递增
  9. A.forEach((_, i) => B[A[i]]++)
  10. // 累计求和
  11. for (let i = 1; i < B.length; i++) {
  12. B[i] = B[i - 1] + B[i]
  13. }
  14. // 结果取出
  15. for (let i = 0; i < A.length; i++) {
  16. const p = B[A[i]] - 1 //回写位置
  17. B[A[i]]--
  18. C[p] = A[i]
  19. }
  20. return C
  21. }
  22. const C = [10, 50, 30, 90, 40, 80, 70]
  23. console.log(counting_sort(C));

基数排序

image.png
image.png
image.png
image.png

队列先进先出

栈先进后出

  1. // 基数排列
  2. function radix_sort (A) {
  3. const max = Math.max(...A)
  4. const buckets = Array.from({ length: 10 }, () => [])
  5. // 有效数位
  6. let m = 1
  7. // 如果当前位数小于最大的数,就需要循环
  8. while (m < max) {
  9. // 将数组放到桶中
  10. A.forEach(number => {
  11. // 求出当前位数
  12. const digit = ~~((number % (m * 10)) / m)
  13. buckets[digit].push(number)
  14. })
  15. // 从桶中取元素
  16. let j = 0
  17. buckets.forEach(bucket =>{
  18. while(bucket.length>0){
  19. A[j++] = bucket.shift()
  20. }
  21. })
  22. // 下一个位置
  23. m *= 10
  24. }
  25. }
  26. const C = [10, 50, 30, 90, 40, 80, 70]
  27. radix_sort(C)
  28. console.log(C);

桶排序

image.png
image.png
image.png
image.png
image.png
image.png

  1. // 桶排序
  2. function insertion_sort_t (A) {
  3. for (let i = 1; i < A.length; i++) {
  4. let p = i - 1
  5. const x = A[p + 1]
  6. while (p >= 0 && A[p] > x) {
  7. A[p + 1] = A[p]
  8. p--
  9. }
  10. A[p + 1] = x
  11. }
  12. }
  13. function bucket_sort (A, k, s) {
  14. const buckets = Array.from({ length: k }, () => [])
  15. // 放入桶中
  16. for (let i = 0; i < A.length; i++) {
  17. const index = ~~(A[i] / s)
  18. buckets[index].push(A[i])
  19. }
  20. // 排序每个桶
  21. for (let i = 0; i < buckets.length; i++) {
  22. insertion_sort(buckets[i])
  23. }
  24. // 取出每个同
  25. return [].concat(...buckets)
  26. }
  27. const C = [10, 50, 30, 90, 40, 80, 70]
  28. console.log(bucket_sort(C, 10, 10));

外部排序

分开每一步,来进行处理
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
如果到时候每一组的数据比较多的时候,就要考虑使用什么排序算法,如果插入排序,就有可能 o(n2)的,就会跑不完,如果是 快排,就需要空间占用多一些,所以需要,到时候实际考虑一下怎么处理