Java之實現插入排序,附其改進--二分檢索的插入排序

關於插入排序,如果忘記了原理,請自行百度或參考《算法導論》第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、結果:

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章