选择排序
1.每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在 序列的起始位置,直到全部待排序的数据元素排完。
简单实现
public class SelectionSort {
/**
*
* @param arr 传入需要排序的数组
*
*/
public static void sort(int arr[]) {
for (int i =0;i<arr.length;i++){
//定义最小元素索引
int minIndex = i;
for (int j =i+1 ;j<arr.length;j++){
if (arr[j]<arr[minIndex]){
/**
* 如果索引j所在元素比minIndex所在元素小,则将其交换
*/
int temp = arr[minIndex];
arr[minIndex] = arr[j];
arr[j] = temp;
}
}
}
for (int a:arr
) {
System.out.println(a+"");
}
}
public static void main(String[] args) {
int arr[] = {3,2,5,6,8,1,9};
sort(arr);
}
}
结果
优化实现
以上为比较的选择实现,仅仅只能比较Integer类型数组,我们稍微优化一下。
package com.cdw.SortBasic;
/**
@author Atomy
@date 2018/2/10
*/
public class SelectSort2 {
private SelectSort2(){};
/**
@param arr 将数组类型改为Comparable,使其适应更多数据类型,类似c++中的模板函数
*/
public static void sort(Comparable arr[]) {
int length = arr.length;
for (int i =0;i<length;i++){
//寻找最小元素的索引
int minIndex = i;
for (int j = i+1 ;j < length;j++){
if (arr[j].compareTo(arr[minIndex])<0){
minIndex = j;
}
}
//将交换数据的代码封装到swap方法中,并用Object类型来定义数组,以此来适应Comparable类型
swap(arr, i, minIndex);
}
}
public static void swap(Object[] arr, int i, int j) {
Object temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
public static void main(String[] args) {
int count = 10000;
//SortUtils为我们自定义的工具类,代码在下方
Integer [] arr = SortUtils.getRandomArray(count,0,count);
sort(arr);
SortUtils.printArray(arr,count);
SortUtils.testSort("com.cdw.SortBasic.SelectSort2",arr);
}
}
自定义排序工具类:
package com.cdw.SortBasic;
import java.lang.reflect.Method;
/**
* 自定义排序工具类方法
* @author Atomy
* @date 2018/2/10
*/
public class SortUtils {
public SortUtils() {
}
/**
* 设置随机randmo 数 组
* @param count 数组大小
* @param arrL 上区间
* @param arrR 下区间
* @return
*/
public static Integer [] getRandomArray(int count,int arrL,int arrR){
/*上区间必须小于下区间*/
if (arrL <= arrR) {
Integer[] arr = new Integer[count];
for (int i = 0; i < count; i++)
arr[i] = new Integer((int) (Math.random() * (arrR - arrL + 1) + arrL));
return arr;
}else {
return new Integer[1];
}
}
/*输出数组结果方法*/
public static void printArray(Integer[] arr,int count){
for (int i = 0;i<count;i++){
System.out.println(arr[i]);
}
}
/*是否是有序数组*/
public static boolean isSorted(Comparable [] arr){
for (int i = 0; i < arr.length ; i++)
if (arr[i].compareTo(arr[i+1])>0)
return false;
return true;
}
/*测试排序方法*/
public static void testSort(String sortClassName,Comparable [] arr){
try {
//通过反射获取到排序方法类名
Class sortClass = Class.forName(sortClassName);
//通过类名和方法名获取对应排序方法
Method method = sortClass.getMethod("sort",new Class[]{Comparable[].class});
Object [] o = new Object[]{arr};
double startTime = System.currentTimeMillis();
method.invoke(null,o);
double endTime = System.currentTimeMillis();
assert isSorted(arr);
System.out.println("sort time : "+(endTime-startTime)/1000+" s");
} catch (Exception e) {
e.printStackTrace();
}
}
}
结果:
sort time : 0.314 s
为什么说选择排序的时间复杂度为n^2,我们可以通过testSort方法来验证一下
public static void main(String[] args) {
int count = 10000;//设置随机数组长度为10000
int count2 = 100000;//设置随机数组长度为100000
//获取随机数组
Integer [] arr = SortUtils.getRandomArray(count,0,count);
Integer [] arr2 = SortUtils.getRandomArray(count2,0,count2);
//测试排序方法
SortUtils.testSort("com.cdw.SortBasic.SelectSort2",arr);
SortUtils.testSort("com.cdw.SortBasic.SelectSort2",arr2);
}
结果:
sort time : 0.132 s
sort time : 14.05 s
由此我们可以发现,二者用时相差将近100倍,但二者数组长度相差才为10倍,可见时间跟空间关系为n^2。