直接插入排序:在逐一取出元素时,该元素与它之前的所有元素找出插入位置,之后移动元素,使之插入。
时间复杂度:平均:o(n^2);最好:o(n);最坏:o(n^2)
空间复杂度:o(1)
稳定性:稳定
public void insertSort(int[] a) {
if(a==null||a.length<2)
return;
for (int i = 0; i < a.length; i++) {
int temp = a[i];
int j = i - 1;
for (; j >= 0; j--) {
if (temp < a[j])
a[j + 1] = a[j];
else
break;
}
a[j + 1] = temp;
}
}
折半插入排序:与直接插入排序的唯一区别在于,在查找元素的插入位置时使用的是折半查找。
时间复杂度:平均:o(n^2);最好:o(n);最坏:o(n^2)
空间复杂度:o(1)
稳定性:稳定
public void halfInsert(int[] a) {
if(a==null||a.length<2)
return;
for (int i = 1; i < a.length; i++) {
int temp = a[i];
int max = i - 1;
int min = 0;
while (min <= max) {
int mid = (max + min) / 2;
if (temp > a[mid]) {
min = mid + 1;
} else if (temp < a[mid]) {
max = mid - 1;
} else {
min = mid + 1;
break;
}
}
for (int j = i - 1; j >= min; j--)
a[j + 1] = a[j];
a[min] = temp;
}
}
希尔排序:把元素按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。
稳定性:不稳定
public void shellSort(int[] a) {
if (a == null || a.length < 2)
return;
int d = a.length;
while (true) {
d /= 2;
for (int k = 0; k < d; k++)
for (int i = d + k; i < a.length; i += d) {
int tmp = a[i];
int j = i - d;
for (; j >= 0 && tmp < a[j]; j -= d)
a[j + d] = a[j];
a[j + d] = tmp;
}
if (d == 1)
return;
}
}
冒泡排序:
时间复杂度:平均:o(n^2);最好:o(n);最坏:o(n^2)
空间复杂度:o(1)
稳定性:稳定
public void bubbleSort(int[] a) {
if (a == null || a.length < 2)
return;
for (int i = 0; i < a.length - 1; i++) {
boolean bool = false;
for (int j = 0; j < a.length - 1 - i; j++) {
if (a[j] > a[j + 1]) {
int temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
bool = true;
}
}
if (!bool)
break;
}
}
选择排序:
时间复杂度:平均:o(n^2);最好:o(n^2);最坏:o(n^2)
空间复杂度:o(1)
稳定性:稳定
public static void selectSort(int[] a) {
if (a == null || a.length < 2)
return;
for (int i = 0; i < a.length - 1; i++) {
int index = i;
boolean bool = false;
for (int j = i + 1; j < a.length; j++) {
if (a[index] > a[j]) {
index = j;
bool = true;
}
}
if (bool) {
int temp = a[index];
a[index] = a[i];
a[i] = temp;
}
}
}
快速排序:
时间复杂度:平均:o(nlog2n);最好:o(nlog2n);最坏:o(n^2)
空间复杂度:o(nlog2n)
稳定性:不稳定
public static void quickSort(int[] a, int low, int high) {
if (low >= high || a == null || a.length < 2)
return;
int l = low;
int h = high;
int key = a[low];
while (l < h) {
while (l < h && a[h] >= key)
h--;
a[l] = a[h];
while (l < h && a[l] <= key)
l++;
a[h] = a[l];
}
a[l] = key;
quickSort(a, low, l - 1);
quickSort(a, l + 1, high);
}
归并排序:
时间复杂度:平均:o(nlog2n);最好:o(nlog2n);最坏:o(nlog2n)
空间复杂度:o(n)
稳定性:稳定
public static void mergeSort(int[] a, int low, int high) {
if (low >= high || a == null || a.length < 2)
return;
int mid = (low + high) / 2;
mergeSort(a, low, mid);
mergeSort(a, mid + 1, high);
sort(a, low, mid, high);
}
private static void sort(int[] a, int low, int mid, int high) {
int[] temp = new int[high - low + 1];
int i = low;
int j = mid + 1;
int k = 0;
while (i <= mid && j <= high) {
if (a[i] <= a[j]) {
temp[k++] = a[i++];
} else
temp[k++] = a[j++];
}
while (i <= mid)
temp[k++] = a[i++];
while (j <= high)
temp[k++] = a[j++];
for (int m = 0; m < temp.length; m++)
a[low + m] = temp[m];
}
堆排序:
时间复杂度:平均o(nlog2n);最好:o(nlog2n);最坏:o(nlog2n)
空间复杂度:o(1)
稳定性:不稳定
public static void heapSort(int[] a) {
if (a == null || a.length < 2)
return;
int length = a.length - 1;
for (int parent = (length - 1) / 2; parent >= 0; parent--) {
adjustHeap(a, parent, length);
}
for (int i = length; i >= 0; i--) {
int temp = a[0];
a[0] = a[i];
a[i] = temp;
adjustHeap(a, 0, i - 1);
}
}
private static void adjustHeap(int[] a, int parent, int length) {
int temp = a[parent];
for (int i = parent * 2 + 1; i <= length; i = i * 2 + 1) {
if (i < length && a[i] < a[i + 1])
i++;
if (temp >= a[i])
break;
a[parent] = a[i];
parent = i;
}
a[parent] = temp;
}
树形选择排序
public static void treeSelectSort(int[] a) {
if (a == null || a.length < 2)
return;
int leafCount = 1;
while (leafCount < a.length)
leafCount *= 2;
int[] tree = new int[leafCount << 1];
for (int i = 0; i < a.length; i++)
tree[tree.length - 1 - i] = a[i];
for (int i = a.length; i < leafCount; i++)
tree[tree.length - 1 - i] = Integer.MIN_VALUE;
for (int i = tree.length - 1; i > 1; i -= 2)
tree[i / 2] = Math.max(tree[i - 1], tree[i]);
a[a.length - 1] = tree[1];
int maxIndex;
for (int i = a.length - 2; i >= 0; i--) {
maxIndex = tree.length - 1;
while (tree[1] != tree[maxIndex])
maxIndex--;
tree[maxIndex] = Integer.MIN_VALUE;
while (maxIndex > 1) {
if (maxIndex % 2 == 0)
tree[maxIndex / 2] = Math.max(tree[maxIndex + 1], tree[maxIndex]);
else
tree[maxIndex / 2] = Math.max(tree[maxIndex - 1], tree[maxIndex]);
maxIndex /= 2;
}
a[i] = tree[1];
}
}
折半查找 :
public int halfSearch(int[] arr, int key) {
int min = 0;
int max = arr.length-1;
int mid = (min + max) / 2;
while (min<=max) {
if (key == arr[mid])
return mid;
else if (key > arr[mid])
min = mid + 1;
else if (key < arr[mid])
max = mid - 1;
mid=(max+min)/2;
}
return -min-1;//返回应该插入的位置
}