思路:
- 1.将数组的第一个元素看成有序的,后面都是无序的
- 2.用无序序列的第一个元素(需要用临时变量将其存起来,以便有序序列的值向后移动)和有序序列中的值作比较(从有序序列的最后一个元素向前比较)
- 3.有序序列的值只要比其大都依次向后移一位
- 4.找到 <= 该元素的位置p,将该元素插入p+1处
初步代码:
public static void insertSort(int[] arr){
for(int i = 1;i < arr.length;i++){ //假设第一个元素是有序的,后面的都要插入排序
if(arr[i] < arr[i - 1]){ //当前元素 < 有序序列中的最后一个元素的情况
int j = 0; //便于返回小于或等于tmp 元素的位置
int tmp = arr[i]; //将当前元素存起来,以便其前面的元素后移
for(j = i - 1;j >= 0;j--){ //从后向前找要插入的位置
if(arr[j] > tmp){
arr[j + 1] = arr[j];
}else {
break; //找到 <= tmp的值的位置
}
}
arr[j + 1] = tmp; //将tmp放到 小于或等于tmp这个元素的后一个位置
}
}
}
public static void swap(int[] arr,int i,int j){
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
复杂度分析:
优化:二分查找该元素要插入的位置
分析:
{1,1,2,3,1} left = 0;right = 3,mid = (right + left)/2 = 1;temp = 1
temp >= arr[mid] 在mid的右边查找 left = mid + 1 = 2;right = 3,mid = (right + left)/2 = 2;temp = 1
temp < arr[mid] 在左边查找 left = 2;right = mid - 1 = 1 right > left 跳出while循环
所以temp 插入位置为temp + 1
代码:
public static void insertSort(int[] arr){
for(int i = 1;i < arr.length;i++){ //假设第一个元素是有序的,后面的都要插入排序
if(arr[i] < arr[i - 1]){ //当前元素 < 有序序列中的最后一个元素的情况
int j = 0; //方便查找小于或等于tmp 元素的位置
int left = 0;
int right = i - 1;
int tmp = arr[i]; //将当前元素存起来,以便其前面的元素后移
while(left <= right){ //折半查找元素要插入的位置
int mid = (right + left)/2;
if(tmp < arr[mid]){
right = mid - 1;
}else {
left = mid + 1;
}
}
for(j = i - 1;j > right;j--){ // 将right后面的元素依次向后移动一位
arr[j + 1] = arr[j];
}
arr[j + 1] = tmp; //将tmp放到 小于或等于tmp这个元素的后一个位置
}
}
}