排序算法Java实现(优化上一篇内容)

10 篇文章 0 订阅

    上一篇文章我学习了使用Java实现了最简单的插入排序算法(InsertionSort)。今天接续跟着马士兵老师学习,他讲到了这个程序还有两个待优化的地方。

    1.看下面代码:

static void sort(int[] array){
		for(int i = 1;i<array.length;i++){ 
			//数组的第一个元素被当作已经排好序的一个数,所以i从1开始。
			for(int j = i;j>0;j--){
				if(array[j]<array[j-1]){
					swap(array,j,j-1);
				}
			}
		}
	}

        上面的代码中,内层的for循环里面有一个条件:if(array[j]<array[j-1])。这个条件可以放到for循环判断条件里面。代码是变成下面的样子:

static void sort(int[] array){
		for(int i = 1;i<array.length;i++){ 
			//数组的第一个元素被当作已经排好序的一个数,所以i从1开始。
			for(int j = i; j>0&&a[j]<a[j-1]; j--){
					swap(array,j,j-1);
			}
		}
	}

        以我的水平,我只能感觉代码少了一行,还不太明白这样的具体好处是什么。哈哈,问题先留着,以后再解决。

2.修改算法,使用临时变量记录标记项,去掉swap()方法。

        这是之前的代码段:

static void sort(int[] array){
		for(int i = 1;i<array.length;i++){ 
			//数组的第一个元素被当作已经排好序的一个数,所以i从1开始。
			for(int j = i;j>0;j--){
				if(array[j]<array[j-1]){
					swap(array,j,j-1);
				}
			}
		}
	}

static void swap(int[] array,int i,int j){
		int temp = array[i];
		array[i] = array[j];
		array[j] = temp;
		                 
	}

        之前的算法不停的调用swap()方法使数组元素归位,调用函数会带来一些开销的:

        调用函数的开销大致可分两个部分:①传递参数的开销②保存当前程序上下文信息所花费的开销。对于传递参数的开销而 言,传递的参数越多开销就越大;对于保存当前程序上下文所花费的开销而言,函数越复杂需要花费的开销就越大。

    sort函数调用swap()方法,参数是一个数组,程序还要保存上下文。为了减少开销提高效率,可使用临时变量记录标记项,去掉swap()方法。

     使用临时变量temp,思路如下图所示:当需要把 2 插入到它前面的序列时,用temp保存2,之前的元素不断向后移动(a[j]=a[j-1]),这样一来就给2腾开了它该在的位置,然后将temp赋值给那个位置。

     修改后的代码(修改后性能提升,我给它取名叫:sortPlus()  哈哈哈):

static void sortPlus(int[] a){
		int temp = 0;
		int j;
		for(int i=1;i<a.length;i++){
			for(j = i;j > 0;j--){
				if(a[j]<a[j-1]){
					temp = a[j];
					a[j] = a[j-1];
					a[j-1] = temp;
				}
				
			}
		}
	}

    这样就不用总调用swap()了。


    代码修改完毕,我们通过数据看一下sort() 和 sortPlus()。自己写了一下测试代码:

    我让两个程序都执行十万次,看看他们的执行时间

static void testSort(int [] a){
		long startTime = System.currentTimeMillis();    //获取开始时间

		for(int i = 0; i<100000;i++){
			sort(a);
		}

		long endTime = System.currentTimeMillis();    //获取结束时间

		System.out.println("十万次sort()运行时间:" + (endTime - startTime) + "ms");    //输出程序运行时间
		
		long startTime1 = System.currentTimeMillis();    //获取开始时间

		for(int i = 0; i<10000;i++){
			sort(a);
		}

		long endTime1 = System.currentTimeMillis();    //获取结束时间

		System.out.println("十万次sortPlus()运行时间:" + (endTime1 - startTime1) + "ms");    //输出程序运行时间
	}

    在main() 方法中调用:

public class InsertionSort {
	public static void main(String[] args) {
		int [] a = {6,5,2,4,9,7,8,5,1,4};
		print(a);
		//sort(a);
		//sortPlus(a);
		//print(a);
		testSort(a);

	}

    执行结果:

    可以看到在程序执行十万次的情况下,SortPlus()是Sort()运行时间的1/5 !

    把十万再增大一下变成一百万看看:

    一百万次下SortPlus()的运行时间大约是Sort()运行时间的1/10。


    上面测试我只考虑了运行次数,应该还要测试在大量待排序数据数据下的运行效率。

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值