1、插入排序:越有序,速度越快 * 最坏情况下(无序) 时间复杂度:O(n^2) * 最好情况下(有序) 时间复杂度:O(n) * 稳定性: 稳定
private static void insertSort(int[] array) {
for (int i = 1; i < array.length; i++) {
int tmp = array[i];
int j = i - 1;
while (j >= 0 && array[j] > tmp) { //如果array[j] >= tmp,就不稳定了
array[j + 1] = array[j];
j--;
}
array[j + 1] = tmp;
}
}
2、希尔排序:缩小增量法,增量最好为素数,最后一个为1;例子:5,3,1 * 最坏情况下(无序) 时间复杂度:O(n^2) * 最好情况下(有序) 时间复杂度:O(n) * 稳定性: 不稳定
private static void shellSort(int[] array) {
int[] drr = {5, 3, 1};
for (int i = 0; i < drr.length; i++) {
shell(array, drr[i]);
}
}
private static void shell(int[] array, int gap) {
for (int i = gap; i < array.length; i++) {
int tmp = array[i];
int j = i - gap;
while (j >= 0 && array[j] > tmp) {
array[j + gap] = array[j];
j = j - gap;
}
array[j + gap] = tmp;
}
}
3、选择排序: * 时间复杂度:O(n) * 稳定性: 不稳定
private static void selectSort(int[] array) {
for (int i = 0; i < array.length; i++) {
for (int j = i + 1; j < array.length; j++) {
if (array[j] < array[i]) {
int tmp = array[i];
array[i] = array[j];
array[j] = tmp;
}
}
}
}
4、 堆排序: * 时间复杂度:O(n*log(n)) * 稳定性:不稳定
private static void heapSort(int[] array) {
for (int i = (array.length - 1 - 1) / 2; i >= 0; i--) {
adjustDown(array, i, array.length);
}
int last = array.length - 1;
while (last > 0) {
int q = array[0];
array[0] = array[last];
array[last] = q;
adjustDown(array, 0, last);
last--;
}
}
private static void adjustDown(int[] array, int root, int index) {
int parent = root;
int child = 2 * parent + 1;
while (child < index) {
//判断是否有右孩子
if (child + 1 < array.length && array[child] < array[child + 1]) {
//此时child是左右孩子中最大值得下标;
child = child + 1;
if (array[child] > array[parent]) {
int tmp = array[parent];
array[parent] = array[child];
array[child] = tmp;
parent = child;
child = 2 * parent + 1;
} else {
break;
}
}
}
}
5、冒泡排序: * 时间复杂度:(O(n^2)) * 稳定性:稳定
private static void bubbleSort(int[] array) {
for (int i = 0; i < array.length - 1; i++) {
boolean flag = false;
for (int j = 0; j < array.length - i - 1; j++) {
if (array[j] > array[j + 1]) {
int tmp = array[j];
array[j] = array[j + 1];
array[j + 1] = tmp;
flag = true;
}
}
if (!flag) {
break;
}
}
}
6、快速排序:
* 时间复杂度:O(n*log(n)),最坏O(n^2)
* 稳定性:不稳定
public static void quickSort(int[] arr) {
if (arr == null || arr.length == 0) {
return;
}
sort(arr, 0, arr.length - 1);
}
private static void sort(int[] a, int low, int high) {
int par = partion(a, low, high);
if (par > low + 1) {
sort(a, low, par - 1);
}
if (par < high - 1) {
sort(a, par + 1, high);
}
}
private static int partion(int[] arr, int low, int high) {
int tmp = arr[low];
while (low < high) {
while (low < high && arr[high] >= tmp) {
high--;
}
arr[low] = arr[high];
while (low < high && (arr[low] <= tmp)) {
low++;
}
arr[high] = arr[low];
}
arr[low] = tmp;
return low;
}
//非递归
private static void quickSort(int[] array) {
Stack<Integer> stack = new Stack<>();
stack.push(0);
stack.push(array.length - 1);
while (!stack.isEmpty()) {
int high = stack.pop();
int low = stack.pop();
if (high < low) {
continue;
}
int par = partion(array, low, high);
if (low < par - 1) {
stack.push(low);
stack.push(par - 1);
}
if (high > par + 1) {
stack.push(par + 1);
stack.push(high);
}
}
}
7、归并排序: * 时间复杂度:O(n*log2(n)) 空间复杂度:O(n) * 稳定性:稳定
//合并两个有序数组
private static void merge(int[] array, int low, int mid, int high) {
int s1 = low;
int s2 = high;
int len = high - low + 1;
int[] tmp = new int[len];
int k = 0;
while (s1 <= mid && s2 <= high) {
if (array[s1] <= array[s2]) {
tmp[k++] = array[s1++];
} else {
tmp[k++] = array[s2++];
}
}
while (s1 <= mid) {
tmp[k++] = array[s1++];
}
while (s2 <= high) {
tmp[k++] = array[s2++];
}
for (int i = 0; i < tmp.length; i++) {
array[low + i] = tmp[i];
}
}
//递归版本
private static void mergeSort(int[] array, int low, int high) {
if (low == high) {
return;
}
int mid = (low + high) / 2;
mergeSort(array, low, mid);
mergeSort(array, mid + 1, high);
merge(array, low, mid, high);
}
//非递归
private static void merge1(int[] array, int gap) {
int[] tmp = new int[array.length];
int i = 0;
int s1 = 0;
int e1 = s1 + gap - 1;
int s2 = e1 + 1;
int e2 = s2 + gap - 1 >=
array.length ? array.length - 1 : s2 + gap - 1;
//当有两个归并段的时候
while (s2 < array.length) {
while (s1 <= e1 && s2 <= e2) {
if (array[s1] <= array[s2]) {
tmp[i++] = array[s1++];
} else {
tmp[i++] = array[s2++];
}
}
while (s1 <= e1) {
tmp[i++] = array[s1++];
}
while (s2 <= e2) {
tmp[i++] = array[s2++];
}
//重新确定s1 e1 s2 e2 的位置
s1 = e2 + 1;
e1 = s1 + gap - 1;
s2 = e1 + 1;
e2 = s2 + gap - 1 >= array.length ? array.length - 1 : s2 + gap - 1;
}
//判断s1 s2
while (s1 < array.length) {
tmp[i++] = array[s1++];
}
for (int t = 0; t < tmp.length; t++) {
array[t] = tmp[t];
}
}
private static void mergeSort1(int[] array) {
for (int gap = 1; gap < array.length; gap *= 2) {
merge1(array, gap);
}
}