八大排序
冒泡排序
/*
稳定排序
时间复杂度:O(n^2)
空间复杂度:O(1)
*/
public static void bubbleSort(int[] nums) {
for (int i = 0; i < nums.length - 1; i++) {
boolean flag = false;
for (int j = 0; j < nums.length - i - 1; j++) {
if(nums[j] > nums[j + 1]) {
flag = true;
Swap.swap(nums, j, j + 1);
}
}
if(!flag) {
break;
}
}
}
选择排序
/*
每次选出剩余元素的最小值放入坑位
时间复杂度:O(n^2)
空间复杂度:O(1)
不稳定 2 2' 1
*/
public static void selectSort(int[] nums) {
for(int i = 0; i < nums.length - 1; ++i) {
int min = i;
for(int j = i + 1; j < nums.length; ++j) {
if(nums[j] < nums[min]) {
min = j;
}
}
Swap.swap(nums, min, i);
}
}
插入排序
/*
从右往左插入扑克牌
稳定排序
时间复杂度:O(n^2), 最好的情况下时O(n)
空间复杂度:O(1)
*/
public static void insertSort(int[] nums) {
for(int i = 1; i < nums.length; ++i) {
int j = i - 1;
while(j >= 0 && nums[j] > nums[j + 1]) {
Swap.swap(nums, j, j + 1);
--j;
}
}
}
希尔排序
/*
不稳定排序
时间复杂度:O(nlog(n))
空间复杂度:O(1)
*/
public static void shellSort(int[] nums) {
int n = nums.length;
int gap = n;
while(gap >= 2) {
gap >>= 1;
for(int i = 0; i < n - gap; ++i) {
int j = i;
while(j >= 0 && nums[j] > nums[j + gap]) {
Swap.swap(nums, j, j + gap);
j -= gap;
}
}
}
}
快速排序
/*
不稳定排序,3,4,4' pivot = 3;
时间复杂度:O(n*log(n))
空间复杂度:O(log(n))
*/
public static void quickSort(int[] nums) {
// 快排不稳定,3,4,4' pivot = 3;
quickSortImpl(nums, 0, nums.length - 1);
}
private static void quickSortImpl(int[] nums, int left, int right) {
if(left >= right) {
return;
}
Random random = new Random();
int pivot = nums[random.nextInt(right - left + 1) + left];
int pl = left - 1;
int pr = right + 1;
for(int i = left; i < pr; ++i) {
if(nums[i] < pivot) {
Swap.swap(nums, i, ++pl);
} else if(nums[i] > pivot) {
Swap.swap(nums, i--, --pr);
}
}
quickSortImpl(nums, left, pl);
quickSortImpl(nums, pr, right);
}
归并排序
/*
稳定
时间复杂度:O(nlog(n))
空间复杂度:O(n)
*/
public static void mergeSort(int[] nums) {
mergeSortImpl(nums, 0, nums.length - 1);
}
private static void mergeSortImpl(int[] nums, int left, int right) {
if(left >= right) {
return;
}
int[] temp = new int[right - left + 1];
int mid = left + ((right - left) >> 1);
mergeSortImpl(nums, left, mid);
mergeSortImpl(nums, mid + 1, right);
int m = left;
int n = mid + 1;
int i = 0;
while(m <= mid && n <= right) {
if(nums[m] <= nums[n]) {
temp[i++] = nums[m++];
} else {
temp[i++] = nums[n++];
}
}
while(n <= right) {
temp[i++] = nums[n++];
}
while(m <= mid) {
temp[i++] = nums[m++];
}
System.arraycopy(temp, 0, nums, left, right - left + 1);
}
堆排序
/*
不稳定排序,1, 2, 2 heapify时不知道两个2的先后顺序
时间复杂度:O(n*log(n))
空间复杂度:O(log(n))
*/
public static void heapSort(int[] nums) {
// 堆排不稳定,1, 2, 2 heapify时不知道两个2的先后顺序
buildHeap(nums, nums.length);
System.out.println(Arrays.toString(nums));
for(int i = nums.length - 1; i >= 0; --i) {
Swap.swap(nums, 0, i);
heapify(nums, i, 0);
}
}
private static void heapify(int[] nums, int n, int i) {
int left = (i << 1) + 1;
int right = (i << 1) + 2;
int max = i;
if(left < n && nums[left] > nums[max]) {
max = left;
}
if(right < n && nums[right] > nums[max]) {
max = right;
}
if(i != max) {
Swap.swap(nums, max, i);
heapify(nums, n, max);
}
}
private static void buildHeap(int[] nums, int n) {
for (int i = (n >> 1) - 1; i >= 0; --i) {
heapify(nums, n, i);
}
}
计数排序
/*
数据范围 0-100;
稳定排序,从后往前放
时间复杂度:O(n + k) , k = 数据范围的最大值-最小值+1
空间复杂度:O(k)
*/
public static void countSort(int[] nums) {
int[] arr = new int[101];
for (int num : nums) {
++arr[num];
}
int cur = 0;
for (int i = 0; i < arr.length; i++) {
if(arr[i] > 0) {
Arrays.fill(nums, cur, cur + arr[i], i);
cur += arr[i];
}
}
}