选择排序

算法第四版读书笔记


写好博客,记住点滴;写明是什么,为什么

目录


选择排序

  • 计算模型

    书中同样采用了一般大众的方法:即计算 比较与交换 的数量;对于不交换元素的算法,则计算访问数组的次数

  • 什么是选择排序(大白话说一下,没有图o(╥﹏╥)o)

    对于一个随机乱序的数组,我们先设置一个索引,指向数组的第一个元素,然后选择其中最小的那个元素,跟数组的第一个元素交换,如果第一个元素是最小的,则跟其自身进行交换;这样一次选择、比较完毕,数组的第一个元素,就可以确定是最小的元素了;接着,将索引往后移动一个,指向数组的第二个元素,再剩下的不确定的元素中,继续选择,把该次选择到的最小的元素,与该次参与选择的数组的第一位进行交换,也就是当前索引指向的数组元素;然后,再次后移索引,继续着前面的操作;当索引移动到数组的最后一个元素时,数组完成排序;


java代码实现

代码中的Example类的具体实现,请看博客中的Example类
//        待排序的数组
        Integer[] a = {12, 2, 5, 6, 77, 6, 7, 4, 87, 23};
        int N = a.length;

        for (int i = 0; i < N; i++) {
//            假设当前索引指向的元素是最小值
            int min = i;
//            用当前假设的最小元素和右边的元素作比较
            for (int j = i + 1; j < N; j++) {
//                如果比假设的最小元素小,则将其记录为最小的,
                if (Example.less(a[j], a[min])) {
                    min = j;
                }
            }
//            交换元素,之前只是记录下脚标
            Example.exch(a, i, min);
        }
//        打印数组
        Example.show(a);

分析

选择排序,是将第 i 的元素,放到数组的第 [i] 位,数组的第 i 元素左边的元素是已经排序完毕的,并且它们的位置不再改变;


复杂度

  • 交换次数

    从代码中我们可以看出,每一趟选择的时候,即使最小的元素,就是我们最初假设的元素,最后依然,会进行一次交换,自身与自身的交换;那么使整个数组有序,我们一共需要交换 N(数组的长度)次;因为每一个元素,要放到它应该放的位置上的时候,都要与该位置上原来的元素,进行一次交换,有N个元素,那么就交换N次;

  • 比较次数

    从代码中,我们会发现,我们用于比较的 if 语句,每次都会被执行;
    外层 for 循环 次执行的时候,执行了(n-1) if 语句;
    外层 for 循环 次执行的时候,执行了(n-2) if 语句;
    外层 for 循环 次执行的时候,执行了(n-3) if 语句;
    ….
    ….
    ….
    外层 for 循环 N 次执行的时候,执行了 1 if 语句;
    因此,一共比较了 (n-1)+(n-2)+(n-3)+….+2+1 次 ;这显然是个等差数列,求和公式套一下,结果是 (n^2)/2 -1/2,取大O阶,就是 n^2, 因此可以看出选择排序是一个复杂度为 N的平方级 算法


特点

  • 数据移动的次数是最少的

    与我后面将要学到的那些算法(插入、希尔、归并、堆、快排等排序算法)作比较,选择排序是数据移动最少的,仅仅移动了N次

  • 运行时间,也就是复杂度和输入没有任何关系

    这样是很不好的,就是说,我们每次选择当前这趟的最小元素,并不会为下一趟排序,做出任何贡献;也就是说,无论我们的输入是什么,都恒定的比较一样多的次数,最好与最坏的结果是一样的;

原文地址:https://www.cnblogs.com/young-youth/p/11665749.html