|
| 1 | +前言 |
| 2 | + |
| 3 | +- 深入总结八大排序算法以及相关的面试算法题 |
| 4 | +- 总结其他算法 |
| 5 | + |
| 6 | +## 进入算法的世界 |
| 7 | + |
| 8 | +#### 1. 冒泡排序 |
| 9 | + |
| 10 | +#### 2. 选择排序 |
| 11 | + |
| 12 | +#### 3. 插入排序 |
| 13 | + |
| 14 | +#### 4. 归并排序 |
| 15 | + |
| 16 | +``` |
| 17 | +//归并排序 |
| 18 | +aux [n...mid..mid+1..m] |
| 19 | +nums [a,b,c,d,e,f,g] |
| 20 | + |
| 21 | + |
| 22 | +private void merge(int[] nums, int left, int mid, int right) { |
| 23 | + int[] aux = Arrays.copyOfRange(nums, left, right + 1); |
| 24 | + int i = left, j = mid + 1; |
| 25 | + for(int k = left; k <= right; k++) { |
| 26 | + if(i > mid) { |
| 27 | + nums[k] = aux[j - left]; |
| 28 | + j++; |
| 29 | + } else if(j > right) { |
| 30 | + nums[k] = aux[i - left]; |
| 31 | + i++; |
| 32 | + } else if(aux[i - left] < aux[j - left]) { |
| 33 | + nums[k] = aux[i - left]; |
| 34 | + i++; |
| 35 | + } else {//aux[i-left] >= aux[j-left] |
| 36 | + nums[k] = aux[j - left]; |
| 37 | + j++; |
| 38 | + } |
| 39 | + } |
| 40 | +} |
| 41 | +private void sort(int[] nums, int left, int right) { |
| 42 | + if(left >= right) { |
| 43 | + return; |
| 44 | + } |
| 45 | + int mid = (right - left) / 2 + left; |
| 46 | + sort(nums, left, mid); |
| 47 | + sort(nums, mid+1, right); |
| 48 | + merge(nums, left, mid, right); |
| 49 | +} |
| 50 | +public void sort(int[] nums) { |
| 51 | + sort(nums, 0, nums.length - 1); |
| 52 | +} |
| 53 | +``` |
| 54 | + |
| 55 | + |
| 56 | + |
| 57 | +#### 5. 快速排序 |
| 58 | + |
| 59 | +``` |
| 60 | +//快速排序 |
| 61 | + nums [a,b,c,d,e,f,g] |
| 62 | + p |
| 63 | + j |
| 64 | + k |
| 65 | + i |
| 66 | +private int partition2(int[] nums, int lt, int gt) { |
| 67 | + int p = nums[n]; |
| 68 | + int j = lt; |
| 69 | + for(int i = lt; i <= gt; i++) { |
| 70 | + if(nums[i] < p) { |
| 71 | + swap(nums, ++j, i); |
| 72 | + } |
| 73 | + } |
| 74 | + swap(nums, lt, j); |
| 75 | + return j; |
| 76 | +} |
| 77 | + |
| 78 | +private int partition(int[] nums, int n, int m) { |
| 79 | + int p = nums[n]; |
| 80 | + int j = n; |
| 81 | + int k = m + 1; |
| 82 | + int i = n + 1; |
| 83 | + while(i < k) { |
| 84 | + if(nums[i] < p) { |
| 85 | + swap(nums, ++j, i++); |
| 86 | + } else if(nums[i] > p) { |
| 87 | + swap(nums, --k, i); |
| 88 | + } else {// nums[i] == p |
| 89 | + i++; |
| 90 | + } |
| 91 | + } |
| 92 | + swap(nums, n, j); |
| 93 | + return j; |
| 94 | +} |
| 95 | +private void swap(int[] nums, int n, int m) { |
| 96 | + int tmp = nums[n]; |
| 97 | + nums[n] = nums[m]; |
| 98 | + nums[m] = tmp; |
| 99 | +} |
| 100 | +private void sort(int[] nums, int n, int m) { |
| 101 | + if(n > m) { |
| 102 | + return; |
| 103 | + } |
| 104 | + int p = partition(nums, n, m); |
| 105 | + sort(nums, n, p - 1); |
| 106 | + sort(nums, p + 1, m); |
| 107 | +} |
| 108 | +public void sort(int[] nums) { |
| 109 | + sort(nums, 0, nums.length); |
| 110 | +} |
| 111 | +``` |
| 112 | + |
| 113 | + |
| 114 | + |
| 115 | +#### 6. 希尔排序 |
| 116 | + |
| 117 | +#### 7. 基数排序 |
| 118 | + |
| 119 | +#### 8. 桶排序 |
| 120 | + |
| 121 | + |
| 122 | + |
| 123 | + |
| 124 | + |
| 125 | +####经典排序 |
| 126 | + |
| 127 | +| 排序名 | 时间复杂度 | 空间复杂度 | 优势 | 劣势 | 适用场景 | 稳定性 | |
| 128 | +| :--: | :------: | :----------: | :--: | :--: | :-----------------------: | :--: | |
| 129 | +| 冒泡排序 | O(n^2) | O(1) | | | | 稳定 | |
| 130 | +| 插入排序 | O(n^2) | O(1) | | | | 稳定 | |
| 131 | +| 归并排序 | O(nlogn) | O(N) | | | | 稳定 | |
| 132 | +| 计数排序 | | O(M) | | | 对于用例少的数据,比如对人的年龄排序或者身高排序。 | 稳定 | |
| 133 | +| 基数排序 | | O(M) | | | | 稳定 | |
| 134 | +| 桶排序 | | | | | | 稳定 | |
| 135 | +| 选择排序 | O(n^2) | O(1) | | | | 不稳定 | |
| 136 | +| 快速排序 | O(nlogn) | O(logn)~O(n) | | | | 不稳定 | |
| 137 | +| 希尔排序 | O(nlogn) | O(1) | | | | 不稳定 | |
| 138 | +| 堆排序 | O(nlogn) | O(1) | | | | 不稳定 | |
| 139 | + |
| 140 | +> 除非面试题特别说明,否则认为要排序的数据范围是均匀分布的。 |
| 141 | + |
| 142 | +> 快速排序之所以叫快速排序,并不代表它比堆排序和归并排序优良。在最好情况下,它的渐进复杂度与 堆排序和归并排序是相同的。知识快速排序的常量系数比较小而已。 |
| 143 | + |
| 144 | +> 类库上提供的排序,并不是某一种算法的实现,而是综合了多种排序的综合排序。当数组比较小时,使用插入排序;当数组较大时,选择快速排序或其他的O(nlogn)的排序。 |
| 145 | + |
0 commit comments