zoukankan      html  css  js  c++  java
  • 排序算法之选择排序

            选择排序是所有排序算法中非常简单又非常基础的算法,逻辑简单、容易实现,好多复杂算法都是由这些简单的算法演变而来。所以想要学好算法,必须先从这些简单算法学起,循序渐进,为后面学习复杂算法打下基础。本篇主要从“基本原理、排序流程、核心代码、算法性能、稳定性、参考代码”等几个方面介绍这一算法。

            基本原理:从待排序列中找到最小(或最大)的元素,和序列的第一个元素交换位置;然后从剩余的元素中找到最小(或最大)的元素,和序列的第二个元素交换位置……以此类推,直到整个序列排序完毕。

            排序流程:以下以序列:5 3 0 4 1 9 7 2 6 8为例,红色元素表示当前序列最小元素,加粗元素表示每一趟参与比较的元素,未加粗元素表示已经排好的元素(未参与比较)。

    趟数 排序前 排序后 说明
    1 5 3 0 4 1 9 7 2 6 8 0 3 5 4 1 9 7 2 6 8 0元素最小,与第一个元素5交换位置
    2 0 3 5 4 1 9 7 2 6 8 0 1 5 4 3 9 7 2 6 8 1元素最小,与第二个元素3交换位置
    3 0 1 5 4 3 9 7 2 6 8 0 1 2 4 3 9 7 5 6 8 2元素最小,与第三个元素5交换位置
    4 0 1 2 4 3 9 7 5 6 8 0 1 2 3 4 9 7 5 6 8 3元素最小,与第四个元素4交换位置
    5 0 1 2 3 4 9 7 5 6 8 0 1 2 3 4 9 7 5 6 8 4元素最小,与第五个元素4交换位置
    6 0 1 2 3 4 9 7 5 6 8 0 1 2 3 4 5 7 9 6 8 5元素最小,与第六个元素9交换位置
    7 0 1 2 3 4 5 7 9 6 8 0 1 2 3 4 5 6 9 7 8 6元素最小,与第七个元素7交换位置
    8 0 1 2 3 4 5 6 9 7 8 0 1 2 3 4 5 6 7 9 8 7元素最小,与第八个元素9交换位置
    9 0 1 2 3 4 5 6 7 9 8 0 1 2 3 4 5 6 7 8 9 8元素最小,与第九个元素9交换位置
    10 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 9元素最小,与第十个元素9交换位置

            最终排序结果为:0 1 2 3 4 5 6 7 8 9。

            核心代码:以Java为例。

    public static void sort(int[] a) {
        int len = a.length;  //数组长度
        for (int i = 0; i < len; i++) {  //第一个for循环指定排序趟数
            int min = i;  //最小元素位置
            for (int j = i+1; j < len; j++) {  //第二个for循环找出序列最小元素
                if (a[j]<a[min]) min = j;  //如果j位置元素小于当前最小元素,则将j位置赋值给min
            }
            int cha = a[i];  //把最小位置元素与i位置元素交换
            a[i] = a[min];
            a[min] = cha;
        }
    }

            算法性能:算法性能的好坏直接决定算法执行效率的高低,衡量算法性能有一些常用的指标,比如时间复杂度、空间复杂度,同时不同的编码、不同的机器硬件等因素也会影响算法执行效率。对于长度为N的序列,选择排序每一趟选择最小元素,都要比较未排序元素的大小,所以比较总次数为:(N-1)+(N-2)+……+2+1=N(N-1)/2;每次选出最小元素进行交换都能排定一个元素,所以交换总次数为:N。综上,时间复杂度为O(N²),空间复杂度为O(1)。

            稳定性:假如序列中存在两个或多个相同的元素,排序之后他们的相对次序不发生改变(如某序列存在Ni=Nj,排序前Ni在Nj前面;排序后Ni依然在Nj前面),则排序算法是稳定的,否则是不稳定的。选择排序是不稳定的排序算法,比如序列[2,2,1],第一趟排序后变成[1,2,2],第一个2(红色)与1交换位置,两个2的相对位置发生改变,所以是不稳定的。

            总的来说选择排序算法是一种非常容易理解和实现的简单排序算法,它的元素移动次数是最少的,只进行N次交换,交换次数和序列大小是线性关系,其余算法大部分增长数量级都是线性对数或是平方级别的。当然,选择排序算法每一趟只会机械的遍历序列来找出最小元素,如果序列已经有序或所有元素都相等,显然这种遍历是多余的,这是选择排序一大缺点。

            参考代码:以Java为例。

    import java.util.Random;
    
    /*
     * 选择排序
     */
    
    public class SelectionSort {
    
        public static void sort(int[] a) {
            int len = a.length;  //数组长度
            for (int i = 0; i < len; i++) {  //第一个for循环指定排序趟数
                int min = i;  //最小元素位置
                for (int j = i+1; j < len; j++) {  //第二个for循环找出序列最小元素
                    if (a[j]<a[min]) min = j;  //如果j位置元素小于当前最小元素,则将j位置赋值给min
                }
                int cha = a[i];  //把最小位置元素与i位置元素交换
                a[i] = a[min];
                a[min] = cha;
            }
        }
        public static void main(String[] args) {
            Random random = new Random();
            int[] arg1 = new int[20];
            for(int n=0;n<20;n++){  //从[0-100]中生成20个随机数
                arg1[n] = random.nextInt(100);
            }
            
            System.out.println("排序前:");
            for (int i = 0; i < arg1.length; i++) {
                System.out.print(arg1[i]+" ");
            }
            System.out.println("
    排序后:");
            long startTime = System.currentTimeMillis();  //获取开始时间
            sort(arg1);
            long endTime = System.currentTimeMillis();  //获取结束时间
            for (int i = 0; i < arg1.length; i++) {
                System.out.print(arg1[i]+" ");
            }
            System.out.println("
    排序时长:"+(endTime-startTime)+"ms");
        }
    }

            运行结果:

    排序前:
    19 31 52 70 44 6 59 54 29 80 95 79 37 48 99 63 77 38 67 33 
    排序后:
    6 19 29 31 33 37 38 44 48 52 54 59 63 67 70 77 79 80 95 99 
    排序时长:0ms

            转载请注明出处 http://www.cnblogs.com/Y-oung/p/7739536.html

            工作、学习、交流或有任何疑问,请联系邮箱:yy1340128046@163.com

  • 相关阅读:
    数据移除的循环
    C#窗体多语言切换(简繁)
    C# 文字转换最简单的方法
    使用CodeDOM动态编译一个字符串表达式
    C#设置WebBrowser默认浏览器
    Image和字节数组互转
    苹果手机的SB系列(8)为什么没有短信全部删除?
    循环删除外键约束
    腾讯云COS自定义域名,支持https,CDN,私有访问
    腾讯云COS请求签名C#版
  • 原文地址:https://www.cnblogs.com/Y-oung/p/7739536.html
Copyright © 2011-2022 走看看