力扣题解

  1. public class Sort {
  2. private int[] aux;
  3. public int[] sortArray(int[] nums) {
  4. // bubbleSort(nums); // 冒泡排序
  5. // doubleBubbleSort(nums); // 双向冒泡排序
  6. // selectionSort(nums); // 选择排序
  7. // insertionSort(nums); // 插入排序
  8. // shellSort(nums); // 希尔排序
  9. // aux = new int[nums.length];
  10. // mergeSort(nums, 0, nums.length - 1); // 归并排序——自顶向下
  11. // mergeSortBU(nums); // 归并排序——自底向上
  12. // quickSort(nums, 0, nums.length - 1); // 快速排序
  13. // heapSort(nums); // 堆排序
  14. // countSort(nums); // 计数排序
  15. return nums;
  16. }
  17. private void exch(int[] nums, int i, int j) {
  18. nums[i] = nums[i] + nums[j] - (nums[j] = nums[i]);
  19. }
  20. /** 冒泡排序 平均时间复杂度 O(n2) 空间复杂度O(1) 稳定 */
  21. private void bubbleSort(int[] nums) {
  22. for (int i = 0; i < nums.length; ++i) {
  23. for (int j = i + 1; j < nums.length; ++j) {
  24. if (nums[j] < nums[i]) exch(nums, i, j);
  25. }
  26. }
  27. }
  28. /** 双向冒泡排序 平均时间复杂度 O(n2) 空间复杂度O(1) 稳定 */
  29. private void doubleBubbleSort(int[] nums) {
  30. int lo = 0, hi = nums.length - 1;
  31. int i;
  32. while (lo < hi) {
  33. for (i = lo; i < hi; ++i) if (nums[i + 1] < nums[i]) exch(nums, i, i + 1);
  34. for (i = hi - 1; i >= lo; --i) if (nums[i + 1] < nums[i]) exch(nums, i, i + 1);
  35. ++lo;
  36. --hi;
  37. }
  38. }
  39. /** 选择排序 平均时间复杂度 O(n2) 空间复杂度O(1) 不稳定 */
  40. // 不稳定举例 58529 -> 28559 两个5的相对位置改变
  41. private void selectionSort(int[] nums) {
  42. int min;
  43. for (int i = 0; i < nums.length; ++i) {
  44. min = i;
  45. for (int j = i + 1; j < nums.length; ++j) {
  46. if (nums[j] < nums[min]) min = j;
  47. }
  48. exch(nums, i, min);
  49. }
  50. }
  51. /** 插入排序 平均时间复杂度 O(n2) 空间复杂度O(1) 稳定 */
  52. private void insertionSort(int[] nums) {
  53. for (int i = 1; i < nums.length; ++i) {
  54. for (int j = i; j > 0 && nums[j] < nums[j - 1]; --j) {
  55. exch(nums, j, j - 1);
  56. }
  57. }
  58. }
  59. /** 希尔排序 平均时间复杂度 O(n2) 空间复杂度O(1) 稳定 */
  60. private void shellSort(int[] nums) {
  61. int h = 1;
  62. while (h < nums.length / 3) h = h * 3 + 1; // 递增序列(1,4,13,40...)
  63. while (h >= 1) {
  64. for (int i = h; i < nums.length; ++i)
  65. for (int j = i; j >= h && nums[j] < nums[j - h]; j -= h) exch(nums, j - h, j);
  66. h /= 3;
  67. }
  68. }
  69. /** 归并排序——自底向上 平均时间复杂度 O(nlogn) 空间复杂度O(n) 稳定 */
  70. private void mergeSortBU(int[] nums) {
  71. int n = nums.length;
  72. for (int size = 1; size < n; size *= 2) {
  73. for (int lo = 0; lo < n - size; lo += size * 2) {
  74. merge(nums, lo, lo + size - 1, Math.min(lo + 2 * size - 1, n - 1));
  75. }
  76. }
  77. }
  78. /** 归并排序——自顶向下 平均时间复杂度 O(nlogn) 空间复杂度O(n) 稳定 */
  79. private void mergeSort(int[] nums, int lo, int hi) {
  80. if (lo >= hi) return;
  81. int mid = lo + (hi - lo) / 2;
  82. mergeSort(nums, lo, mid);
  83. mergeSort(nums, mid + 1, hi);
  84. merge(nums, lo, mid, hi);
  85. }
  86. private void merge(int[] nums, int lo, int mid, int hi) {
  87. int i = lo, j = mid + 1;
  88. arraycopy(nums, lo, aux, lo, hi - lo + 1);
  89. for (int k = lo; k <= hi; ++k) {
  90. if (i > mid) nums[k] = aux[j++];
  91. else if (j > hi) nums[k] = aux[i++];
  92. else if (aux[i] < aux[j]) nums[k] = aux[i++];
  93. else nums[k] = aux[j++];
  94. }
  95. }
  96. /** 快速排序 平均时间复杂度 O(nlogn) 空间复杂度 O(1) 不稳定 */
  97. private void quickSort(int[] nums, int lo, int hi) {
  98. if (lo >= hi) return;
  99. int mid = partition(nums, lo, hi);
  100. quickSort(nums, lo, mid - 1);
  101. quickSort(nums, mid + 1, hi);
  102. }
  103. private int partition(int[] nums, int lo, int hi) {
  104. int i = lo, j = hi + 1;
  105. int val = nums[lo];
  106. while (true) {
  107. while (nums[++i] < val) if (i == hi) break;
  108. while (val < nums[--j]) if (j == lo) break;
  109. if (i >= j) break;
  110. exch(nums, i, j);
  111. }
  112. exch(nums, lo, j);
  113. return j;
  114. }
  115. /** 计数排序 平均时间复杂度 O(k*n) 空间复杂度 O(k) 稳定 */
  116. private void countSort(int[] nums) {
  117. int max = -50001, min = 50001;
  118. for (int val : nums) {
  119. max = Math.max(val, max);
  120. min = Math.min(val, min);
  121. }
  122. int[] counter = new int[max - min + 1]; // 计数器
  123. for (int val : nums) {
  124. ++counter[val - min];
  125. }
  126. int idx = 0;
  127. int cnt;
  128. for (int val = min; val <= max; ++val) {
  129. cnt = counter[val - min]; // 重复数
  130. while (cnt-- > 0) nums[idx++] = val;
  131. }
  132. }
  133. private void heapSort(int[] nums) {
  134. int n = nums.length;
  135. for (int i = n / 2; i >= 1; --i) {
  136. sink(nums, i, n);
  137. }
  138. while (n > 1) {
  139. exch(nums, 1, n--);
  140. sink(nums, 1, n);
  141. }
  142. }
  143. private void sink(int[] nums, int k, int n) {
  144. int j;
  145. while (2 * k <= n) {
  146. j = 2 * k;
  147. if (j < n && nums[j] < nums[j + 1]) ++j;
  148. if (nums[j] <= nums[k]) break;
  149. exch(nums, k, j);
  150. k = j;
  151. }
  152. }
  153. }

总结

排序 —— 待整理 - 图1

可以去力扣这题练习