十大排序
![排序总结图]()
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
/**
* @author Ogleede
* @Description
* @create 2022-07-31-16:28
*/
public class sort {
static class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
}
}
private static Random rd = new Random(20220731);
public static void swap(int[] arr, int x, int y) {
int tmp = arr[x];
arr[x] = arr[y];
arr[y] = tmp;
}
/**
* 冒泡排序
*/
public static void bubbleSort(int[] arr) {
if (arr == null || arr.length < 2) return;
int n = arr.length;
for (int i = 0; i < n - 1; ++i) {
for (int j = i + 1; j < n; ++j) {
if (arr[j] < arr[i]) {
swap(arr, i, j);
}
}
}
}
/**
* 快速排序
*/
public static int partition(int[] arr, int l, int r) {
int idx = l + rd.nextInt(r - l);
swap(arr, l, idx);
int pivot = arr[l], pivotIdx = l;
for (int i = l + 1; i <= r; ++i) {
if (arr[i] < pivot) {
swap(arr, i, ++pivotIdx);
}
}
swap(arr, l, pivotIdx);
return pivotIdx;
}
public static void quickSort(int[] arr, int l, int r) {
if (l >= r) return;
int idx = partition(arr, l, r);
int tl = idx - 1, tr = idx + 1;
while (tl >= l && arr[tl + 1] == arr[tl]) --tl;
while (tr <= r && arr[tr - 1] == arr[tr]) ++tr;
quickSort(arr, l, tl);
quickSort(arr, tr, r);
}
/**
* 插入排序
*/
public static void insertSort(int[] arr) {
int n = arr.length;
int preIdx = 0, cur = 0;
for (int i = 1; i < n; ++i) {
preIdx = i - 1;
cur = arr[i];
while (preIdx >= 0 && arr[preIdx] > cur) {
arr[preIdx + 1] = arr[preIdx];
--preIdx;
}
arr[preIdx + 1] = cur;
}
}
/**
* 希尔排序
*/
public static void shellSort(int[] nums) {
int n = nums.length;
for (int gap = n / 2; gap > 0; gap >>= 1) {
for (int i = gap; i < n; ++i) {
int j = i, cur = nums[i];
while (j - gap >= 0 && cur < nums[j - gap]) {
nums[j] = nums[j - gap];
j -= gap;
}
nums[j] = cur;
}
}
}
/**
* 选择排序
*/
public static void selectSort(int[] nums) {
int n = nums.length;
int min = 0, minIdx = 0;
for (int i = 0; i < n; ++i) {
min = Integer.MAX_VALUE;
for (int j = i; j < n; ++j) {
if (nums[j] < min) {
min = nums[j];
minIdx = j;
}
}
swap(nums, i, minIdx);
}
}
/**
* 堆排序
*/
public static void heapify(int[] nums, int n, int i) {
if (i >= n) return;
int c1 = 2 * i, c2 = 2 * i + 1;
int max = i;
if (c1 < n && nums[c1] > nums[max]) max = c1;
if (c2 < n && nums[c2] > nums[max]) max = c2;
if (max != i) {
swap(nums, i, max);
heapify(nums, n, max);
}
}
public static void buildHeap(int[] nums, int n) {
int lastNode = n - 1;
int parentNode = lastNode / 2;
for (int i = parentNode; i >= 0; --i) {
heapify(nums, n, i);
}
}
public static void heapSort(int[] nums) {
int n = nums.length;
buildHeap(nums, n);
for (int i = n - 1; i > 0; --i) {
swap(nums, i, 0);
heapify(nums, i, 0);
}
}
/**
* 归并两个排序列表,递归
*/
public static ListNode mergeTwoLists1(ListNode l1, ListNode l2) {
if (l1 == null) {
return l2;
} else if (l2 == null) {
return l1;
} else if (l1.val < l2.val) {
l1.next = mergeTwoLists1(l1.next, l2);
return l1;
} else {
l2.next = mergeTwoLists1(l1, l2.next);
return l2;
}
}
/**
* 归并两个排序链表,迭代
*/
public static ListNode mergeTwoLists2(ListNode l1, ListNode l2) {
if (l1 == null && l2 == null) return null;
if (l2 == null) return l1;
else if (l1 == null) return l2;
ListNode dh = new ListNode(0), p = dh;
if (l1.val < l2.val) {
p.next = l1;
l1 = l1.next;
} else {
p.next = l2;
l2 = l2.next;
}
p = p.next;
while (l1 != null && l2 != null) {
if (l1.val < l2.val) {
p.next = l1;
l1 = l1.next;
} else {
p.next = l2;
l2 = l2.next;
}
p = p.next;
}
if (l1 != null) p.next = l1;
if (l2 != null) p.next = l2;
return dh.next;
}
/**
* 归并多个排序链表
*/
public static ListNode mergeKLists(ListNode[] lists) {
if (lists == null || lists.length == 0) return null;
int k = lists.length, idx = k;
while (idx > 1) {
idx = 0;
for (int i = 0; i < k; i += 2) {
if (i == k - 1) {
lists[idx++] = lists[i];
} else {
lists[idx++] = mergeTwoLists1(lists[i], lists[i + 1]);
}
}
k = idx;
}
return lists[0];
}
/**
* 归并排序,非静态,一个tmp数组
*/
private int[] tmp;
public void mergeSort(int[] nums, int l, int r) {
if (l >= r) return;
int mid = (l + r) >> 1;
mergeSort(nums, l, mid);
mergeSort(nums, mid + 1, r);
int m = l, n = mid + 1;
for (int i = l; i <= r; ++i) {
if (m == mid + 1) {
tmp[i] = nums[n++];
} else if (n == r + 1) {
tmp[i] = nums[m++];
} else if (nums[m] < nums[n]) {
tmp[i] = nums[m++];
} else {
tmp[i] = nums[n++];
}
}
for (int i = l; i <= r; ++i) {
nums[i] = tmp[i];
}
}
/**
* 归并排序,静态创建多个小tmp数组
*/
public static void mergeSort2(int[] nums, int l, int r) {
if (l >= r) return;
int mid = (l + r) >> 1;
mergeSort2(nums, l, mid);
mergeSort2(nums, mid + 1, r);
int m = l, n = mid + 1;
int[] tmp = new int[r - l + 1];
for (int i = l; i <= r; ++i) {
if (m == mid + 1) {
tmp[i - l] = nums[n++];
} else if (n == r + 1) {
tmp[i - l] = nums[m++];
} else if (nums[m] < nums[n]) {
tmp[i - l] = nums[m++];
} else {
tmp[i - l] = nums[n++];
}
}
for (int i = l; i <= r; ++i) {
nums[i] = tmp[i - l];
}
}
/**
* 计数排序
*/
public static void countSort(int[] nums) {
if (nums == null || nums.length < 2) return;
int min = Integer.MAX_VALUE, max = Integer.MIN_VALUE;
for (int num : nums) {
min = Math.min(min, num);
max = Math.max(max, num);
}
int[] counts = new int[max - min + 1];
for (int num : nums) {
++counts[num - min];
}
int idx = 0;
for (int j = 0; j < counts.length; ++j) {
for (int i = counts[j]; i > 0; --i) {
nums[idx++] = j + min;
}
}
}
/**
* 桶排序
*/
public static void bucketSort(int[] nums, int bucketSize) {
if (nums == null || nums.length < 2) return;
int min = Integer.MAX_VALUE, max = Integer.MIN_VALUE;
for (int num : nums) {
min = Math.min(min, num);
max = Math.max(max, num);
}
int bucketCnt = (max - min) / bucketSize + 1;
List<Integer>[] buckets = new List[bucketCnt];
int[] res = new int[nums.length];
for (int i = 0; i < buckets.length; ++i) {
buckets[i] = new ArrayList<>(bucketSize);
}
for (int num : nums) {
buckets[(num - min) / bucketSize].add(num);
}
int idx = 0;
for (int i = 0; i < buckets.length; ++i) {
//省事儿不再桶排序了
Collections.sort(buckets[i]);
for (int j : buckets[i]) {
nums[idx++] = j;
}
//继续递归桶排序
// if (bucketSize == 1) {
// for (int i : bucket) {
// res[idx++] = i;
// }
// } else {
// //再次递归调用桶排序。做题的时候可以直接用别的排序了。
// // if (bucketCnt == 1) {
// // bucketSize--;
// // }
// // List<Integer> temp = sort(bucketArr.get(i), bucketSize);
// // for (int j = 0; j < temp.size(); j++) {
// // resultArr.add(temp.get(j));
// // }
// Collections.sort(bucket);
// for (int i : bucket) {
// res[idx++] = i;
// }
// }
}
}
/**
* 基数排序
* 如果有负数的情况,想到几种处理方式:
* 1.数组右移,整体变成非负数,可能会越界。
* 2.多开10个桶,20个桶一起比较
* 3.只开10个桶,正负分开处理。
*/
public static void radixSort(int[] nums) {
int len = nums.length;
int max = Integer.MIN_VALUE;
for (int num : nums) {
max = Math.max(max, num);
}
int time = (max + "").length();
List<Integer>[] buckets = new List[10];
for (int i = 0, n = 1; i < time; ++i, n *= 10) {
for (int num : nums) {
int tmp = num / n % 10;
if (buckets[tmp] == null) {
buckets[tmp] = new ArrayList<>();
}
buckets[tmp].add(num);
}
int idx = 0;
for (List<Integer> bucket : buckets) {
if (bucket == null || bucket.isEmpty()) continue;
for (int j : bucket) {
nums[idx++] = j;
}
}
}
}
public static void main(String[] args) {
int[] arr = {-1, -10, 907, 3, 888, 666, 666, 907};
for (int j : arr) {
System.out.print(j + " ");
}
System.out.println();
quickSort(arr, 0, arr.length - 1);
for (int j : arr) {
System.out.print(j + " ");
}
}
}
参考
排序总结