3个O(n²)排序
 一、选择排序
简单选择排序:每次从待排序的序列中选择最小的元素放到前面
 1. 从前往后排序
arr[i…n)未排序,arr[0…i)已排序
arr[i…n)中的最小值放到arr[i]的位置
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 
 | function selectSort (arr) {for (let i = 0; i < nums.length - 1; i++) {
 
 let minIndex = i
 for (let j = i + 1; j < nums.length; j++) {
 if (nums[j] < nums[minIndex]) {
 minIndex = j
 }
 }
 if (minIndex !== i) {
 swap(nums, minIndex, i)
 }
 }
 }
 
 | 
 2. 从后往前排序
arr[0…i]未排序,arr(i…n)已排序
arr[0…i]中的最大值放到arr[i]的位置
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 
 | function selectSort (arr) {for (let i = nums.length - 1; i >= 1; i--) {
 
 let maxIndex = i
 for (let j = i - 1; j >= 0; j--) {
 if (nums[j] > nums[maxIndex]) {
 maxIndex = j
 }
 }
 if (maxIndex !== i) {
 swap(nums, maxIndex, i)
 }
 }
 }
 
 | 
 二、冒泡排序
冒泡排序:从头到尾/从尾到头,按顺序两两比较,每一趟将最小/最大值交换到最左/最右边
 1. 从前往后排序
| 12
 3
 4
 5
 6
 7
 8
 9
 
 | function bubbleSort (arr) {for (let i = 0; i < arr.length - 1; i++) {
 for (let j = 0; j < arr.length - i - 1; j++) {
 if (arr[j] > arr[j + 1]) {
 swap(arr, j, j + 1)
 }
 }
 }
 }
 
 | 
 优化1
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 
 | function bubbleSort (arr) {for (let i = 0; i < arr.length - 1; i++) {
 let isSwapped = false
 for (let j = 0; j < arr.length - i - 1; j++) {
 if (arr[j] > arr[j + 1]) {
 swap(arr, j, j + 1)
 isSwapped = true
 }
 }
 if (!isSwapped) {
 break
 }
 }
 }
 
 | 
 优化2
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 
 | function bubbleSort (arr) {for (let i = 0; i < arr.length - 1;) {
 let lastSwappedIndex = 0
 for (let j = 0; j < arr.length - i - 1; j++) {
 if (arr[j] > arr[j + 1]) {
 swap(arr, j, j + 1)
 lastSwappedIndex = j + 1
 }
 }
 i = arr.length - lastSwappedIndex
 }
 }
 
 | 
 2. 从后往前排序
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 
 | function bubbleSort (arr) {for (let i = 0; i < arr.length - 1; i++) {
 let isSwapped = false
 for (let j = arr.length - 1; j - 1 >= 0 + i; j--){
 if (arr[j] < arr[j - 1]) {
 swap(arr, j, j - 1)
 isSwapped = true
 }
 }
 
 if (!isSwapped){
 break
 }
 }
 }
 
 
 | 
 优化
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 
 | function bubbleSort (arr) {for (let i = 0; i < arr.length - 1;) {
 let lastSwappedIndex = arr.length - 1
 for (let j = arr.length - 1; j - 1 >= 0 + i; j--){
 if (arr[j] < arr[j - 1]) {
 swap(arr, j, j - 1)
 lastSwappedIndex = j - 1
 }
 }
 i = lastSwappedIndex + 1
 }
 }
 
 | 
 三、插入排序
插入排序:按顺序从待排序序列中取出一个并插入前面已经排序好的序列中
 1. 从前往后排序
arr[i…n)未排序,arr[0…i)已排序
把arr[i]放到arr[0…i)中合适的位置
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 
 | function insertSort (arr) {for (let i = 1; i < arr.length; i++) {
 for (let j = i; j - 1 >= 0; j--) {
 if (arr[j] < arr[j - 1]) {
 swap(arr, j, j - 1)
 } else {
 break
 }
 }
 }
 }
 
 
 function insertSort (arr) {
 for (let i = 1; i < arr.length; i++) {
 for (let j = i; j - 1 >= 0 && arr[j] < arr[j - 1]; j--) {
 swap(arr, j, j - 1)
 }
 }
 }
 
 | 
 优化
arr[i…n)未排序,arr[0…i)已排序
存储arr[i], 找到arr[i]应该存放的位置
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 
 | function insertSort (arr) {for (let i = 1; i < arr.length; i++) {
 const temp = arr[i]
 let j
 for (j = i; j - 1 >= 0 && temp < arr[j - 1]; j--) {
 arr[j] = arr[j - 1]
 }
 arr[j] = temp
 }
 }
 
 | 
 2. 从后往前排序
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 
 | function insertSort (arr) {for (let i = arr.length - 2; i >= 0; i--) {
 const temp = arr[i]
 let j
 for (j = i; j + 1 <= arr.length - 1 && temp > arr[j + 1]; j++) {
 arr[j] = arr[j + 1]
 }
 arr[j] = temp
 }
 }
 
 | 
 helper.js
| 12
 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
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 
 | 
 
 
 function swap (arr, i, j) {
 const temp = arr[i]
 arr[i] = arr[j]
 arr[j] = temp
 
 
 
 
 
 }
 
 
 
 
 
 function generateOrderedArray (n) {
 const arr = new Array(n)
 for (let i = 0; i < n; i++)
 arr[i] = i
 return arr
 }
 
 
 
 
 
 function generateRandomArray (n, bound) {
 const arr = new Array(n)
 for (let i = 0; i < n; i++)
 arr[i] = ~~(Math.random() * bound)
 return arr
 }
 
 
 
 
 
 function generateRandomArrayByStartAndEnd (n, start, end) {
 const arr = new Array(n)
 for (let i = 0; i < n; i++)
 arr[i] = ~~(Math.random() * (end - start + 1) + start)
 return arr
 }
 
 
 
 
 
 function isSorted (arr) {
 for (let i = 1; i < arr.length; i++)
 if (arr[i - 1] > arr[i])
 return false
 return true
 }
 
 
 
 
 
 function testSort (fn, arr) {
 const startTime = Date.now()
 fn(arr)
 const endTime = Date.now()
 const spendTime = endTime - startTime
 if (!isSorted(arr)) {
 console.log(`${fn.name} failed!`)
 const debugArr = generateRandomArray(5, 10)
 console.log(`Before sort: [${debugArr.join(', ')}]`)
 fn(debugArr)
 console.log(`After sort: [${debugArr.join(', ')}]`)
 return
 }
 
 console.log(`${fn.name}: ${arr.length}, time: ${spendTime / 1000}s`)
 }
 
 
 module.exports = {
 swap,
 generateOrderedArray,
 generateRandomArray,
 generateRandomArrayByStartAndEnd,
 isSorted,
 testSort
 }
 
 |