选择排序简单实现和复杂度估计

选择排序

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。

猜你喜欢

转载自blog.csdn.net/a923338627/article/details/79591996