關於插入排序,如果忘記了原理,請自行百度或參考《算法導論》第2章,溫故而知新!。關於改進的插入排序,方式1的時間複雜度沒有明顯改進,方式2一般情況下可以明顯縮短時間。關於其時間複雜度的研究,還請自行腦補。
1、插入排序的java源碼:
/**
* 插入排序:從小到大
* @param array
* @return 排序花費的時間
*/
public static long insertSort(int[] array){
long beginTime = System.currentTimeMillis();
for(int i=1;i<array.length;i++){
int temp = array[i];//temp 作爲要插入的值
int j=i-1;
//往前搜索,大於temp的值往後搬
while(j>=0 && array[j]>temp){
array[j+1] =array[j];
j--;
}
//由循環不變性,可知插入之前的子數組都是排好序的,所以直接從第一個小於temp值處插入(前面的數肯定小於temp)
array[j+1]=temp;
}
long endTime = System.currentTimeMillis();
return endTime- beginTime;
}
2、改進的插入排序(植入二分檢索)java源碼:
實現方式1(時間與輸入的數組原順序不同有差異):
/**
* 改進的插入排序(植入二分查找):從小到大--不穩定
* @param array
* @return 排序花費的時間
*/
public static long insertSortImprove(int[] array){
long beginTime = System.currentTimeMillis();
int min =-1;
int max =-1;
int mid =-1;
for(int i=1;i<array.length;i++){
//保證前兩個數有序
if(array[i]>array[i-1]){
continue;
}
int temp = array[i];
//通過二分法查找
min = 0 ;
max = i-1;
while(min <= max){
mid= (min+max)/2;
if(array[mid] == temp){
break;
}
if(array[mid] <temp){
min = mid+1;
}else {
max = max-1;
}
}
//將值往後搬
for(int k=i;k>mid;k--){
array[k] = array[k-1];
}
array[mid] = temp;
}
long endTime = System.currentTimeMillis();
return endTime- beginTime;
}
方式2(一般情況下,會縮短排序時間):
public static long insertSortImprove(int[] array){
long beginTime = System.currentTimeMillis();
int high,low,mid=0;
for(int i=1;i<array.length;i++){
int temp = array[i];
high = i;
low = 1;//low==0,以0開始會出錯,index=0時
mid = (high+low)/2;//與放在循環裏有區別!
while(low<=high){
if(array[mid-1] == temp) {
break ;//相等就跳出,不能少,否則出現相等的數判斷是會死循環!
}
else if(array[mid-1] > temp){
high = mid - 1;
mid = (high+low)/2;
}
else{
low = mid + 1;
mid = (high+low)/2;
}
}
for(int k=i;k>mid;k--){
array[k] = array[k-1];
}
array[mid]=temp;
}
long endTime = System.currentTimeMillis();
return endTime- beginTime;
}
3、調式源碼:
/**
* 插入排序的改進
* 加入二分法檢索
* @author Smilexs
*
*/
public class InsertSort {
private static int N = 10;//排序數
public static void main(String[] args) {
long sortTime = 0;
int[] array1 = new int[N];
int[] array2 = new int[N];
//初始化數組,隨機整數賦值
for(int i=0;i<N;i++){
int temp = (int)(Math.random()*N);
array1[i] = temp;
array2[i] = temp;
}
System.out.println("原數組:"+Arrays.toString(array1));
//插入排序
sortTime = insertSort(array1);
// System.out.println("普通的插入排序時間:"+sortTime+"ms");
System.out.println("普通的插入排序:"+Arrays.toString(array1));
//二分檢索的插入排序
sortTime = insertSortImprove(array2);
// System.out.println("二分法檢索的插入排序時間:"+sortTime+"ms");
System.out.println("二分法檢索的插入排序:"+Arrays.toString(array2));
}}
4、結果: