算法系列--排序算法(三)选择排序

定义 
        选择排序
顾名思义就是选择其中一个符合条件的元素直接放到排列完成时候的位置。每次选出当前集合中的一个最值。
        特点被选中的元素经过一轮比较会直接找到自己的位置。“选择排序” 和 “冒泡排序” 都比较适合“前5名”“后5名”...这种问题。
图解

        (1)、选择数组中最小的元素值以及位置,默认第一位的【3】是最小值;

3 1 4 2 5 8 7

        (2)、以【3】是最小值向后比较,【1】< 【3】,最小值变成【1】下标【1】;

3 1 4 2 5 8 7

        (3)、以【1】是最小值向后比较,直到数组最后一个元素,期间只是游标变化,数组元素并没有移动;

3 1 4 2 5 8 7

        (4)、然后在交换【1】与当时起始位置的数据交换(从第几位开始比较与谁交换,比较过程是确定选择的值是整个范围内的最值);

1 3 4 2 5 8 7

       以上为一次选择过程,选择排序同样是需要多次选择组成的。

       每次选择结果如下:

3 1 4 2 5 8 7
1 3 4 2 5 8 7
1 2 4 3 5 8 7
1 2 3 4 5 8 7
1 2 3 4 5 8 7
1 2 3 4 5 8 7
1 2 3 4 5 7 8


       下面算时间复杂度:
       如上图,N 个元素的数组需要(N-1)次选择过程,每次递减的比较次数 如 第一次:需要(N-1)次比较;
       (N-1)+ (N-2) + ... + 1 = N(N-1)/2 , 所以时间复杂度 O(N^2)。

       有人比较在意 稳定性,那么自己思考一下什么情况下元素会改变位置,会不会发生不稳定的情况?
       当然会啊,你再移动其他元素的时候,会交换对应位置的元素,这时候就有可能发生交换;但是是一定会发生么?
       也不是,如果你相同的元素恰好是当前要排序的元素是不会被交换的。
       也就是说“一次选择的过程是不会交换两个相同元素的位置的,多次就不一定了;所以选择排序是不稳定的!”。

有点单薄补个代码:

    /**
     * 选择排序
     *
     * @param array 目标数组
     * @param flag  升序-0 降序-1
     * @return 源数组
     */
    public static int[] selectSort(int[] array, boolean flag) {
        for (int i = 0; i < array.length - 1; i++) {
            int index = i, min = array[i];
            for (int j = i + 1; j < array.length; j++) {
                if (min > array[j] ^ flag) {
                    min = array[j];
                    index = j;
                }
            }
            if (index != i) {
                array[index] = array[i];
                array[i] = min;
            }
        }
        return array;
    }

       一天一个算法今天就分享这些了....

猜你喜欢

转载自blog.csdn.net/Joker_honey/article/details/81539388