1. 排序思路
- 将数组分为"有序表"和"无序表"
- "有序表"初始为第一个数,"无序表"为剩下数组
- 不断的将"无序表"的首位"取出",与"有序表"逐个比较,寻找插入点
- 当比较到达 “有序表” 首位 或 待插入数值 >= "有序表"的当前位置,找到插入点,停止查找
- 否则,将 当前待插入点前一位数值 放入 当前待插入点,待插入点前移一位,继续遍历"有序表"
- 当"无序表"为1时,排序完成
- 优化: 见 希尔排序
2. 复杂度分析
- T(n) = n + 1 + n * (n - 1) + 1 = n2 = O(n2)
3. 代码实现
/**
* 简单插入排序
* 思路:
* - 将数组分为"有序表"和"无序表"
* - "有序表"初始为第一个数,"无序表"为剩下数组
* - 不断的将"无序表"的首位"取出",与"有序表"逐个比较,寻找插入点
* - 当比较到达 "有序表" 首位 或 待插入数值 >= "有序表"的当前位置,找到插入点,停止查找
* - 否则,将 当前待插入点前一位数值 放入 当前待插入点,待插入点前移一位,继续遍历"有序表"
* - 当"无序表"为1时,排序完成
* 复杂度分析:
* - T(n) = (n + 1) + n * (n - 1) + 1 = n^2 = O(n^2)
* @param originalArray - 原始数组
* @return - 排序后数组(不改变原始数组)
*/
public static int[] insertSort(int[] originalArray) {
// 1. 复制数组
int[] sortedArray = new int[originalArray.length];
for (int i = 0; i < originalArray.length; i++) {
sortedArray[i] = originalArray[i];
}
// 2. 大循环:遍历整个数组,每轮的 i 即为此轮"无序表"的首位数下标
for (int i = 1; i < sortedArray.length; i++) {
// 2.1 设置int变量储存本轮循环要插入的位置下标;设置int变量储存要插入的数值("无序表"首位数)
int positionForInserting = i;
int insertNumber = sortedArray[i];
// 2.2 小循环:遍历"有序表",将"无序表"的首位与"有序表"逐个比较,寻找插入点
// 若达到"有序表"的首位,或 待插入数值 >= positionForInserting - 1数值(找到插入点),停止本轮小循环
while (positionForInserting - 1 >= 0 && insertNumber < sortedArray[positionForInserting - 1]) {
sortedArray[positionForInserting] = sortedArray[positionForInserting - 1];
positionForInserting--;
}
// 将 待插入数值 插入 待插入点
sortedArray[positionForInserting] = insertNumber;
}
// 3. 返回排好序的数组
return sortedArray;
}