原理:
將數組分爲有序區和無序區,然後循環將無序區中的元素與有序區中的元素進行比較插入到有序區中,最終將無序區中的元素都移動到有序區中,整個排序過程結束。
要點:
設置哨兵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]
}
}