Java实现选择排序及与冒泡排序的比较

已有的排序方法往往不能很好的满足在实际开发中的所有需求,因此需要不断探索去发现更高效的方法。

------------------------

为什么要出现选择排序?

      前面论述了冒泡排序的思想,并通过Java进行了代码实现。我们知道在冒泡排序中,我们需要从左向右依次进行俩俩比较,且每一次比较都有需要进行交换的可能性,所以若不够幸运,一次排序将交换接近N*N次。要知道一点,交换的过程是要在内存中进行的,即数据在内存中的移动(注:Java语言不会发生位置移动,而只是进行了引用位置的交换),这个过程要比单纯的比较更应该得到使用者的关注。但对于此文中的选择排序而言,情况就大不一样了,虽然此方法也面临着比较次数接近N*N的量级,但是交换次数却能被有效的控制在N次以内。这样看来,其较冒泡排序具有很大的优越性。

思想——

      从左侧索引值为index=0的位置向右进行扫描比较获取数据中的最小值,将最小值直接交换到索引值index的位置,下一次将从index++的位置进行扫描,而如果左侧将要进行比较的数就是剩余数的最小值(即arr[index]=min)将不进行交换,(也就是为什么交换次数可能小于N的原因)。

为了便于理解,我们仍然引用《Java数据结构和算法》一书中的例子进行说明:


代码实现——

import java.util.Random;
import java.util.Scanner;
public class SelectSort{
	//test the bubbleSort
	public static void main(String[] aegs){
		Scanner sc=new Scanner(System.in);
		int[] array=null;
		//produce a array
		ArrayUtil util=new ArrayUtil();
		System.out.println("Please set array`s size:");
		int size=sc.nextInt();
		array=util.produce(size);
		System.out.println("Before sort!");
		util.show(array);
		Sort s=new Sort(array);
		array=s.sortArray();
		//show sorted array
		System.out.println("After sort!");
		util.show(array);
		System.out.format("compairsion_times:%d--exchange_times:%d",s.getComparisiontimes(),s.getExchangetimes());
	}
}
class Sort{
	private int[] arr=null;
	private int EXCHANGE_TIMES=0;
	private int COMPIRASION_TIMES=0;
	public Sort(int[] array){
		arr=array;
	}
	//selectSort(进行选择排序)
	public int[] sortArray(){
		//this array is not empty
		if(arr!=null&&arr.length>0){
		//sort array
                for(int i=0;i<arr.length-1;i++){
			int minNum=arr[i]; //default minNum is arr[i]
			int index=0;   //minNum`s index
			for(int j=i+1;j<arr.length;j++){
				COMPIRASION_TIMES++;
				if(minNum>arr[j]){
					minNum=arr[j];
					index=j;
				}
			}
			//swap number(if arr[i] is minNum ,will not need swap)
			if(minNum!=arr[i]){
				arr[index]=arr[i];
				arr[i]=minNum;
				EXCHANGE_TIMES++;
			}
		    }
		       return arr;
		}else{
			return null;
		}
	}
	//get exchange times
	public int getExchangetimes(){
		return EXCHANGE_TIMES;
	}
	
	//get comparision times
	public int getComparisiontimes(){
		return COMPIRASION_TIMES;
	}
}
//tool class
class ArrayUtil{
	private int[] arr=null;
	//make a array
	public int[] produce(int num){
		Random rand=new Random(500);
		arr=new int[num];
		for(int i=0;i<num;i++){
			arr[i]=rand.nextInt(100);
		}
		return arr;
	}
	//show array
	public void show(int[] array){
		if(array!=null){
			for(int a:array){
				if(a==array[array.length-1]){
				  System.out.format("%d\n",a);
				}else{
				  System.out.format("%d->",a);
				}
			}
		}
	}

} 

运行结果:


与冒泡排序对比——

冒泡排序结果:


从俩个实验结果中可以清楚看到俩种排序方法在数据相同的情况下,选择排序的交换次数明显少于冒泡排序。那么究竟这个因素是否会影响运行效率呢?我们在ArrayUtil类中添加如下方法,并修改main方法来获得运行时间进行对比:

//get run time(ArrayUtil中添加此方法以获取当前时间)
public long getRuntime(){
	return System.currentTimeMillis();
}
long beginTime=util.getRuntime();//排序开始时间
array=s.sortArray();
long endTime=util.getRuntime();//排序结束时间
System.out.format("Runtime----%ds",(endTime-beginTime));//排序花费时间

测试结果(采用个数相同的同一组数据进行比较):

数据个数 冒泡交换次数 选择交换次数 冒泡排序用时(s) 选择排序用时(s)
10 36 6 0 0
100 2615 97 0 0
1000 253631 980 6 4
10000 25120656 9888 139 90

经过实测发现,当数据级较小时虽交换次数有明显不同,但是运行效率基本上没有差距,但是当数据级达到一个量级时效率差距会越来越大,此时选择排序较冒泡排序的优越性不言而喻。

猜你喜欢

转载自blog.csdn.net/goodli199309/article/details/80463772