排序
交换、插入、选择、归并
稳定:a在b前,a = b,排序后,a仍在b前。
不稳定:a在b前,a=b,排序后,a可能在b后。
空间复杂度
快排:O(NlogN)
归并:O(N)
其余O(1)。
时间复杂度
冒泡:O(N^2)
快排:O(Nlog(N))
简单插入:O(N^2)
希尔:O(N^s)
选择:O(N^2)
堆排:O(NlogN)
归并:O(NlogN)
交换排序
- 冒泡 稳定——平均O(n^2),最好O(n),最坏O(n^2)
- 快排 不稳定——平均O(NlogN),最好O(NlogN),最坏O(N^2)
冒泡排序
package com.sort; public class BubleSort implements Sort{ private void swap(int[] nums, int j, int i) { int tem = nums[j]; nums[j] = nums[i]; nums[i] = tem; } @Override public void sort(int[] nums) { for(int i = 0;i < nums.length;i++){ for(int j = nums.length - 1;j > 0;j--){ if(nums[j] < nums[j - 1]){ swap(nums,j,j - 1); } } } } }
快排
package com.sort; public class QuickSort implements Sort{ @Override public void sort(int[] nums) { quickSort(nums, 0, nums.length - 1); } private void quickSort(int[] nums, int i, int j) { if (i >= j) return; int mid = partition(nums, i, j); quickSort(nums, i, mid - 1); quickSort(nums, mid + 1, j); } private int partition(int[] nums, int l, int h) { int base = nums[l]; int i = l, j = h + 1; while (true) { while (++i < h && nums[i] < base) ; while (--j > l && nums[j] > base) ;
if(i >= j) break; swap(nums, i, j); } swap(nums, j, l); return j; } private void swap(int[] nums, int i, int j) { int tem = nums[i]; nums[i] = nums[j]; nums[j] = tem; } }
插入排序
- 插入排序 稳定——O(N^2),最坏 O(N^2),最好O(N)
- 希尔排序 不稳定——O(N^1.3),最坏O(N^2),最好O(N)
插入排序
package com.sort; public class InsertSort implements Sort { @Override public void sort(int[] nums) { for (int i = 0; i < nums.length - 1; i++) { for (int j = i + 1; j > 0; j--) { if (nums[j] < nums[j - 1]) { swap(nums,j,j - 1); } } } } private void swap(int[] nums, int j, int i) { int tem = nums[i]; nums[i] = nums[j]; nums[j] = tem; } }
希尔排序
package com.sort; public class ShellSort implements Sort{ @Override public void sort(int[] nums) { int h = 1; while (h < nums.length / 3) { h = h * 3 + 1; } while (h != 0) { for (int i = h; i < nums.length; i += h) { for (int j = i; j >= h && nums[j] < nums[j - h]; j -= h) { swap(nums, j, j - h); } } h = h / 3; } } private void swap(int[] nums, int j, int i) { int tem = nums[i]; nums[i] = nums[j]; nums[j] = tem; } }
选择排序
分为简单选择排序和堆排序。
简单选择排序
找到未排序数组中的最小元素,放至未排序数组的开头。不稳定。
时间复杂度:3个O(N^2),空间复杂度O(1)
public class ChooseSort extends Sort{ @Override void sort(int[] nums) { for(int i = 0;i < nums.length;i++){ int k = i; for(int j = i + 1;j < nums.length;j++){ //不稳定 2 4453,会将第一个4与3交换,造成不稳定 if(nums[j] < nums[k]){ k = j; } } swap(nums, i, k); } } }
堆排序
时间复杂度,3个O(NlogN),空间O(1)
package com.sort; public class HeapSort extends Sort { @Override void sort(int[] nums) { for (int i = 0; i < nums.length; i++) { heapInsert(nums, i); } for(int i = nums.length - 1;i >= 0;i--){ swap(nums, 0, i); heapify(nums, 0, i); } } private void heapify(int[] nums, int i, int j) { int left = 2 * i + 1; int right = 2 * i + 2; int largest = i; while (left < j) { if (nums[left] > nums[i]) { largest = left; } if (right < j && nums[right] > nums[largest]) { largest = right; } if (largest == i) break; swap(nums, largest, i); i = largest; left = 2 * i + 1; right = 2 * i + 2; } } private void heapInsert(int[] nums, int i) { int parent = 0; while (i != 0) { parent = (i - 1) / 2; if (nums[i] > nums[parent]) { swap(nums, i, parent); i = parent; } else { break; } } } }
归并排序
二路归并排序
时间复杂度:
package com.sort; public class MergeSort extends Sort { int[] help; @Override void sort(int[] nums) { help = new int[nums.length]; mergeSort(nums, 0, nums.length - 1); } private void mergeSort(int[] nums, int i, int j) { if (i >= j) { return; } int mid = (j - i) / 2 + i; mergeSort(nums, i, mid); mergeSort(nums, mid + 1, j); merge(nums, i, mid, j); } private void merge(int[] nums, int start, int mid, int end) { for (int i = start; i <= end; i++) { help[i] = nums[i]; } int k = start, i = start, j = mid + 1; while (k <= end) { if (i > mid) { nums[k++] = help[j++]; } else if (j > end) { nums[k++] = help[i++]; } else if (help[i] < help[j]) { nums[k++] = help[i++]; } else { nums[k++] = help[j++]; } } } }