简单排序
冒泡排序
时间复杂度为O(n^2),数量较大时,性能越低。
public static void main(String[] args) {
Integer[] arr = {4, 3, 5,2, 1, 6};
Bubble.sort(arr);
System.out.println(Arrays.toString(arr)); // [1, 2, 3, 4, 5, 6]
}
public class Bubble {
/* 排序 */
public static void sort(Comparable[] a) {
// i 为每轮的最大索引, i 最小为1, 只剩一个元素是,不需要比较,因此只需 要数组长度减1轮
for (int i = a.length - 1; i > 0; i--) {
// j 为每次比较的前驱元素的索引
for (int j = 0; j < i - 1; j++) {
if (greater(a[j], a[j + 1])) {
exchange(a, j, j+1);
}
}
}
}
/* v 是否大于 w */
public static boolean greater(Comparable v, Comparable w) {
return v.compareTo(w) >= 0;
}
/* 交换位置 */
public static void exchange(Comparable[] a, int i, int j) {
Comparable temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
选择排序
时间复杂度为O(n^2),数量较大时,性能越低。
public static void main(String[] args) {
Integer[] arr = {14, 23, 45,24, 31, 16};
Selection.sort(arr); System.out.println(Arrays.toString(arr));
// [14, 16, 23, 24, 31, 45]
}
public class Selection {
/* 排序 */
public static void sort(Comparable[] a) {
for (int i = 0; i < a.length - 1; i++) {
int minIndex = i;
for (int j = i + 1; j < a.length; j++) {
if (greater(a[minIndex], a[j])) {
minIndex = j;
}
}
exchange(a, minIndex, i);
}
}
/* v 是否大于 w */
public static boolean greater(Comparable v, Comparable w) {
return v.compareTo(w) >= 0;
}
/* 交换位置 */
public static void exchange(Comparable[] a, int i, int j) {
Comparable temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
插入排序
将数据分为“已排序”和“未排序“两组 时间复杂度为O(n^2),数量较大时,性能越低。
public static void main(String[] args) {
Integer[] arr = {98, 12, 23,1, 3, 5};
Insertion.sort(arr); // [1, 3, 5, 12, 23, 98]
System.out.println(Arrays.toString(arr));
}
/* 排序 */
public static void sort(Comparable[] a) {
for (int i = 1; i < a.length; i++) {
for (int j = i; j > 0; j--) {
if (greater(a[j-1], a[j])) {
exchange(a, j-1, j);
}else {
break;
}
}
}
}
高级排序
希尔排序(插入排序升级版)
public static void main(String[] args) {
Integer[] arr = {8, 12, 23,1, 3, 5, 7};
Shell.sort(arr);
// [1, 3, 5, 7, 8, 12, 23]
System.out.println(Arrays.toString(arr));
}
public static void sort(Comparable[] a) {
// 确定希尔增量 h
int len = a.length;
int h = 1;
while (h < len / 2 ) {
h = h * 2 + 1;
}
while (h >= 1) {
for (int i = h; i < len; i++) {
for (int j = i; j >= h; j-=h) {
if (greater(a[j-h], a[j])) {
exchange(a, j-h, j);
}else {
break;
}
}
}
h = h / 2;
}
}
归并排序(递归思想,分治思想)
需要额外创建数组来辅助排序,增加空间复杂度,以空间换时间
public static void main(String[] args) {
Integer[] arr = {8, 212, 2323,41, 43, 5, 7};
Merge.sort(arr);
// [5, 7, 8, 41, 43, 212, 2323]
System.out.println(Arrays.toString(arr));
}
public class Merge {
private static Comparable[] temp;
public static void sort(Comparable[] a) {
temp = new Comparable[a.length];
int right = a.length - 1;
int left = 0;
sort(a, left, right);
}
public static void sort(Comparable[] a, int left, int right) {
if (left < right) {
int mid = left + (right - left)/2;
sort(a, left, mid);
sort(a, mid + 1, right);
merge(a, left, mid, right);
}
}
public static void merge(Comparable[] a, int left, int mid, int right) {
int i = left; // 临时数组的下标
int p1 = left; // 左边数组的下标
int p2 = mid + 1; // 右边数组的下标
while (p1 <= mid && p2 <= right) {
if (less(a[p1], a[p2])) {
temp[i++] = a[p1++];
}else {
temp[i++] = a[p2++];
}
}
while (p1 <= mid) {
temp[i++] = a[p1++];
}
while (p2 <= right) {
temp[i++] = a[p2++];
}
while (left <= right) {
a[left] = temp[left];
left++;
}
}
public static boolean less(Comparable x, Comparable y) {
return x.compareTo(y) < 0;
}
}
快速排序
public class Quick {
public static void main(String[] args) {
Integer[] a = {4, 6, 2, 8, 2, 12, 9, 25, 23};
sort(a);
System.out.println(Arrays.toString(a));
}
public static void sort(Comparable[] a) {
int left = 0;
int right = a.length - 1;
sort(a, left, right);
}
public static void sort(Comparable[] a, int left, int right) {
if (left < right) {
int sep = partition(a, left, right);
sort(a, left, sep - 1);
sort(a, sep + 1, right);
}
}
public static int partition(Comparable[] a, int left, int right) {
Comparable key = a[left];
int lead = left;
int trailing = right + 1;
while (true) {
while (less(key, a[--trailing])) {
if (lead == trailing) {
break;
}
}
while (less(a[++lead], key)) {
if (right == lead) {
break;
}
}
if (lead >= trailing) {
break;
}else {
exchange(a, lead, trailing);
}
}
exchange(a, left, trailing);
return trailing;
}
public static boolean less(Comparable x, Comparable y) {
return x.compareTo(y) < 0;
}
public static void exchange(Comparable[] a, int t, int w) {
Comparable temp = a[t];
a[t] = a[w];
a[w] = temp;
}
}