排序是将一组对象按照某种逻辑顺序重新排列的过程。
排序算法 | 简述 | 时间复杂度 |
---|---|---|
选择排序 | ||
插入排序 | ||
希尔排序 | ||
冒泡排序 | ||
归并排序 | ||
堆排序 | ||
基数排序 |
排序模板
public void sort(Comparable[] a) {
/* 具体算法实现 */
}
public boolean less(Comparable v, Comparable w) {
return v.compareTo(w) < 0;
}
public void each(Comparable[] a, int i, int j) {
Comparable t = a[i];
a[i] = a[j];
a[j] = t;
}
public boolean isSorted(Comparable[] a) {
for (int i = 1; i < a.length; i++) {
if (less(a[i], a[i - 1])) {
return false;
}
}
return true;
}
public void show(Comparable[] a) {
for (int i = 0; i < a.length; i++) {
System.out.println(a[i]);
}
}
复制代码
选择排序
一种最简单的排序算法。首先,找到数组中最小的那个元素,其次,将它和数组的第一个元素交换位置。再次,在剩下的元素中找到最小的元素,将它与数组的第二个元素交换位置。如此往复,直到将整个数组排序。
public void sort(Comparable[] a) {
int size = a.length;
for (int i = 0; i < size - 1; i++) {
for (int j = i + 1; j < size; j++) {
if (less(a[i], a[j])) {
each(a, i, j);
}
}
}
}
排序前 :36 97 28 8 87 19 25 4 84 2
第0次:97 36 28 8 87 19 25 4 84 2
第1次:97 87 28 8 36 19 25 4 84 2
第2次:97 87 84 8 28 19 25 4 36 2
第3次:97 87 84 36 8 19 25 4 28 2
第4次:97 87 84 36 28 8 19 4 25 2
第5次:97 87 84 36 28 25 8 4 19 2
第6次:97 87 84 36 28 25 19 4 8 2
第7次:97 87 84 36 28 25 19 8 4 2
第8次:97 87 84 36 28 25 19 8 4 2
排序后 :97 87 84 36 28 25 19 8 4 2
复制代码
经过了 N-1 次交换 和 (N-1) + (N-2) + (N-3) + ... + 2 + 1 = (N-1)(N)/2 次比较。
插入排序
插入排序的基本思想是:每步将一个待排序的记录,按其关键码值的大小插入前面已经排序的文件中适当位置上,直到全部插入完为止。
public void sort(Comparable[] a) {
int size = a.length;
for (int i = 1; i < size; i++) {
for (int j = i; j > 0 && less(a[j - 1], a[j]); j--) {
each(a, j, j - 1);
}
}
}
排序前 :55 75 23 33 16 40 99 53 56 9
第1次:75 55 23 33 16 40 99 53 56 9
第2次:75 55 23 33 16 40 99 53 56 9
第3次:75 55 33 23 16 40 99 53 56 9
第4次:75 55 33 23 16 40 99 53 56 9
第5次:75 55 40 33 23 16 99 53 56 9
第6次:99 75 55 40 33 23 16 53 56 9
第7次:99 75 55 53 40 33 23 16 56 9
第8次:99 75 56 55 53 40 33 23 16 9
第9次:99 75 56 55 53 40 33 23 16 9
排序后 :99 75 56 55 53 40 33 23 16 9
复制代码
希尔排序
希尔排序(Shell's Sort)是插入排序的一种又称“缩小增量排序”(Diminishing Increment Sort),是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法。
public void sort(Comparable[] a) {
int size = a.length;
for (int step = size / 2; step > 0; step = step / 2) {
for (int i = step; i < size; i++) {
for (int j = i - step; j >= 0 && less(a[j], a[j + step]); j = j - step) {
each(a, j, j + step);
}
}
}
}
排序前 :39 77 2 35 78 81 65 22 17 20
步长5: 81 77 22 35 78 39 65 2 17 20
步长2: 81 77 78 39 65 35 22 20 17 2
步长1: 81 78 77 65 39 35 22 20 17 2
排序后 :81 78 77 65 39 35 22 20 17 2
复制代码
冒泡排序
它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。
public void sort(Comparable[] a) {
int size = a.length;
for (int i = 0; i < size - 1; i++) {
for (int j = 0; j < size - i - 1; j++) {
if (less(a[j], a[j + 1])) {
each(a, j, j + 1);
}
}
}
}
排序前 :37 53 74 82 93 24 25 31 69 23
第0次:53 74 82 93 37 25 31 69 24 23
第1次:74 82 93 53 37 31 69 25 24 23
第2次:82 93 74 53 37 69 31 25 24 23
第3次:93 82 74 53 69 37 31 25 24 23
第4次:93 82 74 69 53 37 31 25 24 23
第5次:93 82 74 69 53 37 31 25 24 23
第6次:93 82 74 69 53 37 31 25 24 23
第7次:93 82 74 69 53 37 31 25 24 23
第8次:93 82 74 69 53 37 31 25 24 23
排序后 :93 82 74 69 53 37 31 25 24 23
复制代码