原理:
将数组分为有序区和无序区,然后循环将无序区中的元素与有序区中的元素进行比较插入到有序区中,最终将无序区中的元素都移动到有序区中,整个排序过程结束。
要点:
设置哨兵i,作为有序区与无序区的分解。
讲解:
设数组为array[0...n-1].
1. 初始时,array[0]自称有序区,无序区为array[1...n-1],令i = 1 ;
2. 将array[i]与有序区array[0...i-1]中的元素进行比较,插入到有序区形成array[0...i] ;
3. i++并重复第2步直到i == n-1,排序结束。
实例:
现有数组[6,2,4,1,9,5],要求对其进行升序排序。
①初始时(图1.1):有序区array[0]={6},无序区array[1-5]={2,4,1,9,5},i == 1,将array[1]=2与有序区进行比较,插入到有序区中,i++,得到图1.2;
②图1.2:有序区array[0,1] = {2,6},无序区array[2-5] = {4,1,9,5},将array[2] = 4与有序区进行比较,插入到有序区中,i++,得到图1.3;
③图1.3:有序区array[0-2] = {2,4,6},无序区array[3-5] = {1,9,5},将array[3] = 1与有序区进行比较,插入到有序区中,i++,得到图1.4;
④图1.4:有序区array[0-3] = {1,2,4,6},无序区array[4,5] = {9,5},将array[4] = 9与有序区进行比较,插入到有序区中,i++,得到图1.5;
⑤图1.5:有序区array[0-4] = {1,2,4,6,9},无序区array[5] = {5},将array[5] = 5与有序区进行比较,插入到有序区中,i++,得到图1.6;
⑥图1.6:有序区array[0-5] = {1,2,4,5,6,9},无序区{},此时i=6 > n-1,排序结束。
程序:
/**
* 插入排序
* @param array 待排序数组
*/
public static void insertSort(int[] array){
int j,temp ;
for(int i = 1;i <= array.length -1;i++){
for(j = i;j > 0;j--){
//如果array[j-1] < array[j],则array[0...j-1]都小于arra[j],不应该再循环内部的for,需要进行优化。
if(array[j] < array[j-1]){
temp = array[j] ;
array[j] = array[j-1] ;
array[j-1] = temp ;
}
}
}
}
/**
* 插入排序(优化内部循环)
* @param array 待排序数组
*/
public static void insertSort2(int[] array){
int j,temp ;
for(int i = 1;i <= array.length -1;i++){
for(j = i;j > 0;j--){
//此时还是会存在不必要的对象交换,应保存比较对象temp = array[i],当array[i-1...0]比array[i]大时,
//元素往后移,直到array[i-1]<temp或者i=0时,设置array[i] = temp,需要进行优化
if(array[j] < array[j-1]){
temp = array[j] ;
array[j] = array[j-1] ;
array[j-1] = temp ;
}else{
break ;
}
}
}
}
/**
* 插入排序(优化元素交换)
* @param array 待排序数组
*/
public static void insertSort3(int[] array){
int j ,temp ;
for(int i = 1;i<=array.length-1;i++){
temp = array[i] ; //保存比较对象
for(j = i;j > 0 && array[j-1] > temp;j--){
array[j] = array[j-1] ; //大的值往后移
}
array[j] = temp ; //找到合适的位置,插入array[i]
}
}