这篇帖子主要是为了总结最常见的排序算法以及应付以后的面试,防止面试突然脑袋 NG。将包括冒泡,插入,快速,归并等常见排序。代码为主,文字仅负责点拨。排序结果为按照升序排序。
初级排序 冒泡排序 提示: 时间复杂度:$O(n)$ ~ $O(n^2)$ 空间复杂度:$O(1)$
1 2 3 4 5 6 7 8 9 10 11 12 13 function bubbleSort (nums ) { let length = nums.length; for (let i = 0 ; i < length - 1 ; i++) { for (let j = 0 ; j < length - 1 - i; j++) { if (nums[j] > nums[j + 1 ]) { let tmp = nums[j]; nums[j] = nums[j + 1 ]; nums[j + 1 ] = tmp; } } } return nums; }
选择排序 提示:每次选最小值与第一个数进行交换 时间复杂度:$O(n)$ ~ $O(n^2)$ 空间复杂度:$O(1)$
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 function selectionSort (nums ) { let length = nums.length; for (let i = 0 ; i < length; i++) { let minIndex = i; for (let j = i; j < length; j++) { if (nums[j] < nums[minIndex]) { minIndex = j; } } let tmp = nums[i]; nums[i] = nums[minIndex]; nums[minIndex] = tmp; } return nums; }
插入排序 提示:将第一个数视为已排好的数组,然后将大于插入对象的数全部像右平移,进行插入 时间复杂度:$O(n)$ ~ $O(n^2)$ 空间复杂度:$O(1)$
1 2 3 4 5 6 7 8 9 10 11 12 function insertionSort (nums ) { for (let i = 1 ; i < nums.length; i++) { let key = nums[i]; let j = i - 1 ; while (j >= 0 && nums[j] > key) { nums[j + 1 ] = nums[j]; j--; } nums[j + 1 ] = key; } return nums; }
高级排序 希尔排序 提示:分治思想,通过设置增量,将其变成若干组插入排序, 时间复杂度:$O(n^{1.3})$ ~ $O(\log_2n)$ ~ $O(n^2)$, 空间复杂度:$O(1)$
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 function shellSort (nums ) { if (nums.length <= 1 ) { return nums; } for (let d = Math .ceil(nums.length / 2 ); d >= 1 ; d = Math .ceil(d / 2 )) { for (let i = 0 ; i < nums.length - d; i++) { for (let j = i; j < nums.length; j = j + d) { if (nums[j] > nums[j+d]) { let tmp = nums[j]; nums[j] = nums[j+d]; nums[j+d] = tmp; } } } } return nums }
快速排序 提示:分治思想 时间复杂度:$O(log_2n)$ ~ $O(n^2)$, 空间复杂度:$O(log_2n)$ ~ $O(n)$
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 function quickSort (nums ) { if (nums.length == 0 ) { return []; } let small = []; let great = []; let pivot = nums[0 ]; for (let i = 1 ; i < nums.length; i++) { if (nums[i] < pivot) { small.push(nums[i]); } else { great.push(nums[i]); } } return quickSort(small).concat(pivot, quickSort(great)); }
归并排序
提示:将数据集分解为一组只有一个元素的 数组,然后创建一组左右子数组将他们合并起来。 时间复杂度:$O(log_2n)$ 空间复杂度:$O(n)$
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 function mergeSort (nums ) { if (nums.length < 2 ) { return nums; } let middleIndex = parseInt (nums.length / 2 ); let left = nums.slice(0 , middle); let right = nums.slice(middle); return merge(mergeSort(left), mergeSort(right)); } function merge (left, right ) { let result = []; for (let i = 0 , j = 0 ; i < left.length && j < right.length;) { if (left[i] > right[j]) { result.push(right[j]); j++; } else { result.push(right[i]); i++; } } while (i < left.length) { result.push(left[i]); i++; } while (j < right.length) { result.push(right[j]); j++; } return result; }