美文网首页
[排序基础]选择排序法SelectionSort

[排序基础]选择排序法SelectionSort

作者: 瑾兰 | 来源:发表于2018-04-23 21:43 被阅读5次
    /**
     * 排序算法 O(N^2)
     *
     * @author Cindy
     * @version $Id SelectionSort.java, v 0.1 2018-04-23 20:54 Administrator Exp $$
     */
    public class SelectionSort {
         public static void swap(int [] arr,int i,int j){
            int t=arr[i];
            arr[i]=arr[j];
            arr[j]=t;
        }
        public static void sort(int[] arr){
            int n=arr.length;
            for (int i = 0; i < n; i++) {
                      // 寻找[i, n)区间里的最小值
                int minIdex=i;
                for (int j = i+1; j <n ; j++) {
                    if(arr[j]<arr[minIdex]){
                            minIdex=j;
                    }
                }
                swap(arr,i,minIdex); // 交换 当前轮最小值
            }
        }
    
        public static void main(String[] args) {
            int[] arr = {10,9,8,7,6,5,4,3,2,1};
            SelectionSort.sort(arr);
            for( int i = 0 ; i < arr.length ; i ++ ){
                System.out.print(arr[i]+"   ");
            }
       }
    

    测试结果:

    1、2、3、4、5、6、7、8、9、10
    

    选择排序在第i轮(i从0开始),找到 [i, n) 这个区间里的最小值,之后和第i个元素交换位置。也就是外循环每轮只会交换元素一次,内循环的目的是找到[i, n)范围内的最小元素。
    以数组:10, 15, 9, 13, 8,为例一共5个元素。

    首先找到索引是 [0, 5) 这个区间里的最小元素,即8。如下图所示:

    [10, 15, 9, 13, 8]

    之后将8和第0个元素,即10交换位置,得到:
    8, 15, 9, 13, 10
    之后,找到索引是 [1, 5) 这个区间里的最小元素,即9。如下图所示:
    8, [15, 9, 13, 10]
    之后将9和第1个元素,即15交换位置,得到:
    8, 9, 15, 13, 10
    之后,找到索引是 [2, 5) 这个区间里的最小元素,即10。如下图所示:
    8, 9, [15, 13, 10]
    之后将10和第2个元素,即15交换位置,得到:
    8, 9, 10, 13, 15
    之后,找到索引是 [3, 5) 这个区间里的最小元素,即13。如下图所示:
    8, 9, 10, [13, 15]
    之后将13和第3个元素,即13交换位置(就是自己),得到:
    8, 9, 10, 13, 15
    其实到这里,排序已经完成了,因为只剩下最后一个元素,此时一定是最大的元素。当然,在程序上,再多做一步,并没有关系,即:
    找到索引是 [4, 5) 这个区间里的最小元素,即15。如下图所示:
    8, 9, 10, 13, [15]
    之后将15和第4个元素,即15交换位置(就是自己),得到:
    8, 9, 10, 13, 15


    上面的排序算法,只能针对一种Integer类型的数字进行排序,如果在进行浮点型数组,双精度类型数组等类型来排序,就不适用了。在这里,我们可以利用模板(泛型)的方式来进行算法编程。
    示例:
    Student.class

    /**
     * 学生类型
     * 姓名,成绩。
     * 按照成绩排序,若相等,则根据姓名字母排序
     * 若成绩不相等,则按照成绩高的考前排序
     * @author Cindy
     * @version $Id Student.java, v 0.1 2018-04-23 22:17 Cindy Exp $$
     */
    public class Student implements Comparable<Student>{
        private String name;
        private int score;
        public Student() {
        }
        public Student(String name, int score) {
            this.name = name;
            this.score = score;
        }
    
        /**
         * 重写Student的compareTo函数
         * if the scores are  equal,
         * sort them according to the alphabetic order of the names.
         * if the scores are not equal, the score is high.
         * @param other
         * @return
         */
        @Override
        public int compareTo(Student other) {
            if(this.score==other.score){
                return this.name.compareTo(other.name);
            }
            if(this.score<other.score){
                return 1;
            }else if(this.score>other.score){
                return  -1;
            }else   // this.score==other.score
                 return 0;
        }
    
        // 定义Student实例的打印输出方式
        @Override
        public String toString() {
            return "Student{" +
                    "name='" + this.name + '\'' +
                    ", score=" + Integer.toString(this.score) +
                    '}';
        }
    }
    
    

    SelectionSortTemplet.Class

    /**
     * 排序算法 O(N^2)
     * 为了是排序算法更加灵活,我们可以使用模板(泛型)编写算法
     * @author Cindy
     * @version $Id SelectionSortTemplet.java, v 0.1 2018-04-23 20:54 Cindy Exp $$
     */
    public class SelectionSortTemplet {
         public static void swap(Object [] arr,int i,int j){
             Object t=arr[i];
            arr[i]=arr[j];
            arr[j]=t;
        }
        public static void sort(Comparable[] arr){
            int n=arr.length;
            for (int i = 0; i < n; i++) {
                int minIdex=i;
                for (int j = i+1; j <n ; j++) {
                    if(arr[j].compareTo(arr[minIdex])<0){
                            minIdex=j;
                    }
                }
                swap(arr,i,minIdex);
            }
        }
    
        public static void main(String[] args) {
            // 测试Integer
            Integer[] a = {10,9,8,7,6,5,4,3,2,1};
            SelectionSortTemplet.sort(a);
            for( int i = 0 ; i < a.length ; i ++ ){
                System.out.print(a[i]+" ");
            }
            System.out.println();
    
    
            // 测试Double
            Double[] b = {4.4, 3.3, 2.2, 1.1};
            SelectionSortTemplet.sort(b);
            for( int i = 0 ; i < b.length ; i ++ ){
                System.out.print(b[i]);
                System.out.print(' ');
            }
            System.out.println();
    
            // 测试String
            String[] c = {"D", "C", "B", "A"};
            SelectionSortTemplet.sort(c);
            for( int i = 0 ; i < c.length ; i ++ ){
                System.out.print(c[i]);
                System.out.print(' ');
            }
            System.out.println();
    
        // 测试自定义的类 Student
            Student[] d = new Student[4];
            d[0] = new Student("D",90);
            d[1] = new Student("C",100);
            d[2] = new Student("B",95);
            d[3] = new Student("A",95);
            SelectionSortTemplet.sort(d);
            for( int i = 0 ; i < d.length ; i ++ ){
                System.out.println(d[i]);
            }
    
        }
    
    }
    
    

    测试结果:

    1 2 3 4 5 6 7 8 9 10 
    1.1 2.2 3.3 4.4 
    A B C D 
    Student{name='C', score=100}
    Student{name='A', score=95}
    Student{name='B', score=95}
    Student{name='D', score=90}
    

    相关文章

      网友评论

          本文标题:[排序基础]选择排序法SelectionSort

          本文链接:https://www.haomeiwen.com/subject/dpbllftx.html