原创不易~看完若对你有所帮助,记得点一个赞哈,这就是对我最大的支持了!

只需要额外几个变量完成:O(1)
需要等规模的额外数组:O(N)
原理之前在第一章节中已经说过了:核心就是遍历找最小值下标,和初始位置替换
public class Code01 {
public static void selectionSort(int[] arr){
// 边界条件
if(arr == null || arr.length < 2){
return;
}
for(int i = 0; i < arr.length - 1; i++){ // i~N-1 范围
int minIndex = i;
for(int j = i+1; j < arr.length ; j++){
// i ~ N-1 中找到最小值下标
minIndex = arr[j] < arr[minIndex] ? j : minIndex;
}
swap(arr, i, minIndex);
}
}
public static void swap(int[] arr,int a,int b){
int tmp = arr[a];
arr[a] = arr[b];
arr[b] = tmp;
}
}
原理:通过遍历原数组,进行大小比较,保证一轮可以将最大值放到最右侧,然后下一轮可以将次大值放到length - 2地方,循环直到结束
public class Code02 {
public static void bubbleSort(int[] arr){
// 边界条件
if(arr == null || arr.length < 2){
return;
}
for(int e = arr.length - 1; e > 0; e--){
for(int i = 0; i < e ; i++){
if(arr[i] > arr[i+1]){
swap(arr,i,i+1);
}
}
}
}
public static void swap(int[] arr,int a,int b){
// 另一种基于异或的swap写法
arr[a] = arr[a] ^ arr[b];
arr[b] = arr[a] ^ arr[b];
arr[a] = arr[a] ^ arr[b];
}
}
插入排序很重要的一点思想是保证局部有序
看0-0范围是否有序,ok
0-1范围是否有序,如果没有做到,交换arr[0]和arr[1],知道有序,ok
0-2范围是否有序,判断arr[2]是否更小,是则跟arr[1]交换,还小,跟arr[0]交换,不是,直接跳过这一次,因为前面步骤已经保证0-1有序!直到有序,ok
…

插入排序和之前冒泡和选择不同的是,他和数据情况是有关系的

例如 7 6 5 4这种数组就是N^2级别
例如 1 2 3 4这种数组就是N级别,但是冒泡或者选择都仍然需要双重遍历才可以
算法这课程都是通过O - 最差情况下的常数操作复杂度,所以这个算法仍然是O(N^2)
但是综合上面其实插入排序在某些数据情况下是会比传统的冒泡和选择排序优秀的,只是最差情况差不多而已。
public static void insertionSort(int[] arr){
if(arr == null || arr.length < 2){
return;
}
// 0-0有序
// 0-N希望有序
for(int i = 1; i < arr.length; i++){
for(int j = i - 1;j >= 0 && arr[j] > arr[j+1];j--){
swap(arr,j,j+1);
}
}
}
