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、结果:

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值