选择排序(Selection Sort)

1、概述

选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。排序趟数为n-1次,n为元素大小。

2、算法原理

对比数组中前一个元素跟后一个元素的大小,如果后面的元素比前面的元素小则用一个变量k来记住他的位置,接着第二次比较,前面“后一个元素”现变成了“前一个元素”,继续跟他的“后一个元素”进行比较如果后面的元素比他要小则用变量min记住它在数组中的位置(下标),等到循环结束的时候,我们应该找到了最小的那个数的下标了,然后进行判断,如果这个元素的下标不是第一个元素的下标,就让第一个元素跟他交换一下值,这样就找到整个数组中最小的数了。然后找到数组中第二小的数,让他跟数组中第二个元素交换一下值,以此类推。

之所以要在交换前进行判断变量min是否发生了变动,是因为若没有发生变动就不需要自己跟自己交换,这样做没有意义,会影响效率。之所以要用变量min来指代数组起始点的下标而不用for循环中的i变量直接做下标,是因为i变量还要控制选择排序的趟数。若i被意外修改了,整个排序也就乱套了。

选择排序是先记住下标,等待一趟排序结束后,才使用最小值的下标进行交换的,这样能增强算法的效率。

附图:

这里写图片描述

3、算法分析

①时间复杂度

选择排序的交换操作介于 0 和 ( n - 1 ) 次之间。选择排序的比较操作为 n ( n - 1) / 2 次之间。选择排序的赋值操作介于 0 和 3 ( n - 1) 次之间。

比较次数O(n²),比较次数与关键字的初始状态无关,总的比较次数N=( n-1)+( n-2)+…+1=n*( n-1)/ 2。交换次数O( n),最好情况是,已经有序,交换0次;最坏情况交换n-1次,逆序交换n/2次。交换次数比冒泡排序少多了,由于交换所需CPU时间比比较所需的CPU时间多,n值较小时,选择排序比冒泡排序快。

②算法稳定性

选择排序是给每个位置选择当前元素最小的,比如给第一个位置选择最小的,在剩余元素里面给第二个元素选择第二小的,依次类推,直到第n - 1个元素,第n个元素不用选择了,因为只剩下它一个最大的元素了。那么,在一趟选择,如果一个元素比当前元素小,而该小的元素又出现在一个和当前元素相等的元素后面,那么交换后稳定性就被破坏了。比较拗口,举个例子,序列5,8,5,2,9,我们知道第一遍选择第1个元素5会和2交换,那么原序列中两个5的相对前后顺序就被破坏了。

因此,选择排序是一种不稳定的排序算法。

4、算法实现(Java)

/**
 * @author Hanlin Wang
 */

//每轮排序,最小值在起始位置处,也就是,往左边堆积最小值。
public class SelectSort {
    public static void main(String[] args) {
        //定义一批随机数
        int[] data = {87,54,26,75,45,1,46,23,2,14,18,3};
        //进行排序
        SelectSort.sort(data);
        //拼接结果
    }

    //定义选择排序
    public static void sort(int[] data){
        for (/*控制起始位置*/int i = 0; /*控制排序轮数*/i < data.length - 1; 
                /*起始位置递增,同时排序轮数递增*/i++) {
            //将每一轮的起始位置i赋值给min,作为最小值角标
            int min = i;
            for (/*起始位置的后面一位为比较对象的起点*/int j = i+1; 

                    /*控制被比较数j的递增次数,
                     * 否则会出现ArrayOutOfBoundsException*/j < data.length; 

                    /*排序一次递增*/j++) {

                //进行判断
                if (data[min] > data[j]) {
                    min = j;
                }
            }

            //若min角标与本轮比较的i的初始值不同,排序过程中min角标发生了变化,交换值。
            if (min != i) {
                SelectSort.swap(data, min, i);
            }

            //本轮排序结果
            String txt = "";
            for (int a : data) {
                txt += a + ",";
            }
            System.out.println("第" + (i+1) + "轮排序的结果为:");
            System.out.println(txt.substring(0, txt.length() - 1) + "
");
        }
    }

    //静态的交换方法
    public static void swap(int[] data, int min, int i){
        int tmp = data[min];
        data[min] = data[i];
        data[i] = tmp;
    }
}

运行结果:

第1轮排序的结果为:
1,54,26,75,45,87,46,23,2,14,18,3

第2轮排序的结果为:
1,2,26,75,45,87,46,23,54,14,18,3

第3轮排序的结果为:
1,2,3,75,45,87,46,23,54,14,18,26

第4轮排序的结果为:
1,2,3,14,45,87,46,23,54,75,18,26

第5轮排序的结果为:
1,2,3,14,18,87,46,23,54,75,45,26

第6轮排序的结果为:
1,2,3,14,18,23,46,87,54,75,45,26

第7轮排序的结果为:
1,2,3,14,18,23,26,87,54,75,45,46

第8轮排序的结果为:
1,2,3,14,18,23,26,45,54,75,87,46

第9轮排序的结果为:
1,2,3,14,18,23,26,45,46,75,87,54

第10轮排序的结果为:
1,2,3,14,18,23,26,45,46,54,87,75

第11轮排序的结果为:
1,2,3,14,18,23,26,45,46,54,75,87

原文地址:https://www.cnblogs.com/wanxi/p/6476224.html