/**
* 插入排序
*
* @author PengHao
* @date 2020-05-21 17:27:17
*/
public class InsertionSort {
/**
* 直接插入排序<br>
* 时间复杂度:<br>
* 1、待排序数组是递增序列,复杂度为O(n)<br>
* 2、待排序数组是递减序列,复杂度为O(n^2)<br>
* 空间复杂度:O(1)<br>
* 稳定性:稳定<br>
*
* @param src 待排序数组
*/
public static void straightInsertionSort(int[] src) {
if (src == null) {
System.err.println("待排序数组不能为null");
return;
}
for (int i = 1; i < src.length; ++i) {
if (src[i - 1] > src[i]) {
int key = src[i];
int j = 0;
// 循环将比key大的数向后挪一位
for (j = i - 1; j >= 0 && src[j] > key; --j) {
src[j + 1] = src[j];
}
// 循环结束说明索引为j的数不存在或者比key小,那么key应该插入到j后面
src[j + 1] = key;
}
}
}
/**
* 折半插入排序<br>
* 时间复杂度:<br>
* 1、待排序数组是递增序列,复杂度为O(n)<br>
* 2、待排序数组是递减序列,复杂度为O(n^2)<br>
* 空间复杂度:O(1)<br>
* 稳定性:稳定<br>
*
* @param src 待排序数组
*/
public static void binaryInsertionSort(int[] src) {
if (src == null) {
System.err.println("待排序数组不能为null");
return;
}
for (int i = 1; i < src.length; ++i) {
if (src[i - 1] > src[i]) {
int key = src[i];
int left = 0, right = i - 1;
// 二分查找第一个比key大的数的索引
while (left < right) {
int mid = left + (right - left >> 1);
if (src[mid] > key) {
right = mid;
} else {
left = mid + 1;
}
}
if (i - left >= 0) {
// 将区间[left, i - 1]整体后移一位到区间[left + 1, i]上
System.arraycopy(src, left, src, left + 1, i - left);
}
src[left] = key;
}
}
}
/**
* 2-路插入排序
*
* @param src 待排序数组
*/
public static void twoWayInsertionSort(int[] src) {
if (src == null) {
System.err.println("待排序数组不能为null");
return;
}
int[] arr = new int[src.length];
arr[0] = src[0];
int first = 0;
int last = 0;
for (int i = 1; i < src.length; ++i) {
if (src[i] < arr[0]) {
if (first == 0) {
first = arr.length - 1;
arr[first] = src[i];
} else {
int j = 0;
for (j = first; j < arr.length && arr[j] < src[i]; ++j) {
arr[j - 1] = arr[j];
}
arr[j - 1] = src[i];
--first;
}
} else {
int j = 0;
for (j = last; j >= 0 && arr[j] > src[i]; --j) {
arr[j + 1] = arr[j];
}
arr[j + 1] = src[i];
++last;
}
}
System.arraycopy(arr, first, src, 0, arr.length - first);
System.arraycopy(arr, 0, src, arr.length - first, last + 1);
}
/**
* 表插入排序<br>
* 时间复杂度:<br>
* 1、待排序数组为递增序列,复杂度为O(n^2)<br>
* 2、待排序数组为递减序列,复杂度为O(n)<br>
* 空间复杂度为O(n)<br>
*
* @param src 待排序数组
*/
public static void listInsertionSort(int[] src) {
if (src == null) {
System.err.println("待排序数组不能为null");
return;
}
int len = src.length;
int[] arr = new int[len + 1];
arr[len] = 0;
arr[0] = len;
for (int i = 1; i < len; ++i) {
int j = len;
// 找到小于src[i]的最大值的索引
while (src[arr[j]] < src[i] && arr[arr[j]] < len) {
j = arr[j];
}
// 将src[i]插入到这个数的后面
arr[i] = arr[j];
arr[j] = i;
}
int[] res = new int[len];
for (int i = arr[len], j = 0; i < len; i = arr[i], ++j) {
res[j] = src[i];
}
System.arraycopy(res, 0, src, 0, len);
}
}
参考
1、数据结构(C语言版)严蔚敏、吴伟民 编著. 清华大学出版社 2007.