• 排序算法六:选择排序之简单选择排序


    声明:引用请注明出处http://blog.csdn.net/finish_dream/article/details/70231398


    引言

    之前已经讲过排序算法系列的插入排序,交换排序。接下来这篇文章和下一篇文章主要讲解选择排序。


    排序相关的基本概念

    • 排序:将一组杂乱无章的数据按一定的规律顺次排列起来。

      • 数据表(data list):它是待排序对象的有限集合。
      • 排序码(key):通常对象有多个属性域,即多个数据成员组成,其中有一个属性域,可用来区分对象,作为排序依据。该域即为排序
        码,每个数据表用哪个属性域作为排序码,要视具体的应用需要而定。
    • 分类

      • 内排序:指在排序期间数据对象全部存放在内存的排序;
      • 外排序:指在排序期间全部对象个数太多,不能同时存放在内存,必须根据排序过程的要求,不断在内、外存之间移动的排序。

    排序的分析

    排序算法的稳定性

    如果在对象序列中有两个对象r[i]和r[j] ,它们的排序码k[i]==k[j] 。如果排序前后,对象r[i]和r[j] 的相对位置不变,则称排序算法是稳定的;否则排序算法是不稳定的。

    排序算法的评价

    时间开销

    • 排序的时间开销可用算法执行中的数据比较次数数据移动次数来衡量。
    • 算法运行时间代价的大略估算一般都按平均情况进行估算。对于那些受对象排序码序列初始排列及对象个数影响较大的,需要按最好情况和最坏情况进行估算。

    空间开销

    算法执行时所需的附加存储。


    分类

    • 简单选择排序
    • 堆排序

    简单选择排序

    基本思想

    首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

    C#代码

        /// <summary>
        /// 交换x,y数值
        /// </summary>
        /// <param name="x">元素1</param>
        /// <param name="y">元素2</param>
        private static void Swap(ref int x, ref int y)
        {
            int tmp = x;
            x = y;
            y = tmp;
        }
    
        /// <summary>
        /// 简单选择排序
        /// </summary>
        /// <param name="array">待排序数组</param>
        /// <returns></returns>
        public static int[] SimpleSelectSort(int[] array)
        {
            if (array.Length > 0)
            {
                int num = array.Length;//数组大小
    
                int tmp;
                for (int i = 0; i < num; i++)//外层遍历控制
                {
                    tmp = i;
                    for (int j = i + 1; j < num; j++)//内层遍历控制
                    {
                        if (array[j] < array[tmp])
                            tmp = j;
                    }
                    Swap(ref array[i], ref array[tmp]);
                }
                return array;
            }
            else
            {
                throw new Exception("待排序数组大小不能小于0");
            }
    
        }
    

    算法分析

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

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

    原地操作几乎是选择排序的唯一优点,当空间复杂度要求较高时,可以考虑选择排序;实际适用的场合非常罕见。


    完整代码被我放在了Github上,感兴趣的可以下下来看一下https://github.com/Finish-Dream/DSAlgorithm

  • 相关阅读:
    查看 Oracle 是32位还是64位的方法
    Oracle 查看 对象 持有 锁 的情况
    Oracle 11.2.0.3 Patchset
    Oracle 升级10.2.0.5.4 OPatch 报错Patch 12419392 Optional component(s) missing 解决方法
    Oracle 11.2.0.1 升级到 11.2.0.3 示例
    Oracle 安装OEM 报错: 无法对所有EM 相关账户解锁 解决方法
    Oracle sessions,processes 和 transactions 参数 关系 说明
    Oracle 11.2.0.1 升级到 11.2.0.3 示例
    Oracle 查看 对象 持有 锁 的情况
    Oracle Database Appliance
  • 原文地址:https://www.cnblogs.com/haxianhe/p/9271049.html
Copyright © 2020-2023  润新知