内部排序概念
1、稳定性:排序之后,原先相等的两个数的先后顺序不发生变化
插入排序
1、直接插入排序O(n^2)稳定
最好时间复杂度O(n):数组已经有序,内层循环一次都不走
/**
* 直接插入排序
* 已排序0--i
* 待排序i--arr.length-1
* 左闭右开
*
* @param arr
*/
public static void insertionSort(int[] arr) {
for (int i = 1; i < arr.length; i++) {
// for (int j = i; j >= 1; j--) {
// if (arr[j] < arr[j - 1]) {
// break;
// }else {
// swap(arr,j,j-1);
// }
// }
for (int j = i; j >= 1 && arr[j] < arr[j - 1]; j--) {
swap(arr, j, j - 1);
}
}
}
优化:折半插入排序
/**
* 折半插入排序,找到待插入的位置,将其搬移出空位,最后value插入该位置。
* 有序区间【0,i)
* 无序区间【i,arr.length)
*/
public static void insertionSortBS(int[] arr) {
for (int i = 0; i < arr.length; i++) {
int val = arr[i];
//有序区间[left,right)左闭右开
int left = 0;
int right = i;
while (left < right) {
int mid = (left + right) / 2;
if (val < arr[mid]) {
right = mid;
} else {
left = mid + 1;
}
}
//搬移【left,i)的元素
for (int j = i; j > left; j--) {
arr[j] = arr[j - 1];
}
arr[left] = val;
}
}
2、希尔排序O(n^1.2 ~ n^1.3)
【希尔排序就是对插入排序的优化,又称为缩小增量排序】
【不断将小数组调整的近乎有序 ,整个大数组就接近有序状态 ,这个时候使用插入排序效率很高】
【核心思想:当数组近乎有序,插入排序效率很高】
【思路:①先选定一个整数gap。将待排序的数据分为gap组,所有距离为gap的为同一组,对每一个小数组进行插入 排序②step.gap = gap /2或者3,重复①,当gap==1,此时整个数组已经调整近乎有序,此时的对数组进行一次插入排序 即可。】
/**
* 希尔排序,缩小增量排序,按照gap将原数组分为gap个子数组,子数组内部先排序
* 不断缩小gap的值,直到gap==1
* 当gap==1时整个数组近乎有序,执行最后一次插入排序
*
* @param arr
*/
public static void shellSort(int[] arr) {
int gap = arr.length >> 1;
//预处理阶段
// while (gap >1 ){
// insertionGap(arr,gap);
// gap =gap>>1;
// }
// insertionSort(arr);
while (gap >= 1) {
insertionGap(arr, gap);
gap = gap >> 1;
}
}
/**
* 极端情况 假设gap==1 就是一个插入排序
*
* @param arr
* @param gap
*/
private static void insertionGap(int[] arr, int gap) {
for (int i = gap; i < arr.length; i++) {
for (