排序

3/22/2022 算法

# 原理

# 1. 冒泡排序如何实现,时间复杂度是多少?

查看答案

冒泡算法的原理:

  • 升序冒泡:两次循环,相邻元素两两比较,如果前面的大于后面的就交换位置
  • 降序冒泡:两次循环,相邻元素两两比较,如果前面的小于后面的就交换位置

冒泡排序的性能:

  • 冒泡排序在平均和最坏情况下的时间复杂度都是 O(n^2)
  • 空间复杂度是 O(1)
  • 稳定
function bubbleSort(arr) {
   for (let i = 0; i < arr.length; i++) {
        for (let j = 0; j < arr.length - 1 - i; j++) {
          if(arr[j] > arr[j+1]) {
            let temp = arr[j]
            arr[j] = arr[j+1]
            arr[j+1] = temp
          }
        }
    }
}
bubbleSort(arr)
1
2
3
4
5
6
7
8
9
10
11
12

# 2. 插入排序

查看答案
  • 插入排序原理是分成有序区和无序区,将无序区中的元素插入到有序区当中,直到全部都成为有序区。
  • 最开始的时候单个元素看做是有序的。
  • 时间复杂度 O(n^2
  • 空间复杂度 O(1)
  • 稳定
function sort (arr) {
      for(let i = 1; i < arr.length; i++) {
        let temp = arr[i]
        for (let j = i - 1; j >= 0; j--) {
          if(arr[j] > temp) {
            arr[j+1] = arr[j]
            if(j === 0) arr[j] = temp
          } else {
            arr[j+1] = temp
            break;
          }
        }
    }
}
sort(arr)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 3. 归并排序

查看答案
  • 简单理解,如果是两个有序数组排序如何排?每个数组头部进行比较,小的弹出,直到遍历完成。
  • 如果将每个数组元素都理解成一个有序数组,进行归并,直到归并成一个完整的数组。
  • 时间复杂度 O(n * logn)
  • 空间复杂度 O(n)
  • 稳定
function mergeSort(arr) {
   if (arr.length < 2) return arr
   let mid = arr.length >> 1
   // 将数组分解成两边
   let left = arr.slice(0,mid)
   left = mergeSort(left)
   let right = arr.slice(mid, arr.length)
   right = mergeSort(right)
   // 合并数组
   return merge(left, right)
}

function merge (l, r) {
   let len = l.length + r.length
   let res = []
   let lindex = 0
   let rindex = 0
   // 遍历,把小的放进数组里
   for (let i = 0; i < len; i++) {
     if(lindex < l.length && rindex < r.length) {
       if (l[lindex] <= r[rindex]) {
         res.push(l[lindex++])
       } else {
         res.push(r[rindex++])
       }
     } else if (lindex >= l.length) {
       res.push(r[rindex++])
     } else {
       res.push(l[lindex++])
     }
   }
   return res
}
const arr1 = mergeSort(arr)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

# 4. 快速排序

查看答案
  • 找到一个数作为参考,比这个数字大的放在数字左边,比它小的放在右边; 然后分别再对左边和右变的序列做相同的操作
  • 时间复杂度 O(n * logn)
  • 不稳定
function quickSort (arr) {
    if (arr.length <= 1) return arr
    const left = []
    const right = []
    const current = arr.splice(0, 1)[0] // 注意splice之后,长度少了一个
    for(let i = 0; i < arr.length; i++) {
      if(arr[i] < current) {
        left.push(arr[i])
      } else {
        right.push(arr[i])
      }
    }
    return quickSort(left).concat(current, quickSort(right)) // 递归
}
quickSort(arr)
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 变形题

# 1. 有一个数组,里面是人名和分数,按照分数进行排序

const arr = [{name: 'xm', score: 97}, {name: 'xh', score: 92}, {name: 'xl', score: 95}, {name: 'xq', score: 96}]

查看答案
arr.sort((a, b) => b.score - a.score)
更新时间: 2022-04-10 13:23