【综合类型第 23 篇】什么是选择排序 ?

这是【综合类型第 23 篇】,如果觉得有用的话,欢迎关注专栏。

一:定义

选择排序是一种简单直观的排序算法,无论什么数据进去都是 O(n²) 的时间复杂度,所以用到它的时候,数据规模越小越好。

二:原理

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

三:动态图演示

在这里插入图片描述

四:C# 代码实现

namespace AlgorithmTest
{
    class Program
    {
        static void Main(string[] args)
        {
            // 定义一个长度为12的数组
            int[] array = new[]{ 3, 8, 15, 48, 2, 14, 21, 13, 56, 32, 33, 16 };
            SelectSort(array);
            Console.ReadKey();
        }

        static void SelectSort(int[] array)
        {
            for (int i = 0; i < array.Length-1; i++)
            {
                int minIndex = i; // 最小元素的下标
                for (int j = i+1; j < array.Length; j++)
                {
                    //记录最小值下标
                    minIndex = array[minIndex] < array[j] ? minIndex : j;
                }
                // 交换位置
                int temp = array[i];
                array[i] = array[minIndex];
                array[minIndex] = temp;
            }
            // 打印结果
            foreach (var item in array)
            {
                Console.Write(item + " ");
            }
        }
    }
}

控制台输出结果如下所示
在这里插入图片描述
由以上代码我们可知

  • 外层循环控制执行轮数,循环的轮数等于元素的个数 - 1。
  • 每一轮中找出无序区域的最小元素,并且把这个最小元素和无序区域的第一个元素交换。

五:选择排序和冒泡排序的对比

1)交换次数的对比

以 { 3, 8, 15, 48, 2, 14, 21, 13, 56, 32, 33, 16 } 这组数据来说,选择排序和冒泡排序分别交换了多少次呢 ?这里我另外补充了代码用来显示执行结果,如下所示
在这里插入图片描述
可见,就该数组而言,选择排序要比冒泡排序交换次数要少,是不是就说明选择排序要比冒泡排序的效率更高呢 ?

答案是否定的,其实不管是排序算法还是其它,都有其"存在即合理"的说法,只不过我们自己要根据不同的场景,选择合适的才是最好的。

2)稳定性对比

冒泡排序虽然存在一定的性能缺陷,但却是一个稳定的排序。

反观选择排序,虽然性能会好点,但是排序具有不稳定性,为什么这样说呢 ?当数列包含多个值相等的元素时,选择排序有可能打乱它们的原有顺序。

接下来举一个例子说明,如下图所示
在这里插入图片描述
上图中,绿色的5 原本排在 橙色的5 之前,但是随着第一轮 元素3 和 绿色5 的交换,使得后续操作中,绿色的5 排在了 橙色的5 之后,所以说选择排序具有不稳定性。

六:为什么要用选择排序 ?

举个简单的实际例子

假设现在有10个人,每个人的身高不一样,需要你按身高从低到高,自左向右排序 。

思路一:冒泡排序
如果你用冒泡排序,假设左边第一个人的身高是最高的,但你还是要先让他和他右边的人交换位置,然后依次类推,一直让他排到最右边,如果现实中你这样做,恐怕脑子真的是冒泡了。所以此时选择冒泡排序是不合适的。

思路二:选择排序
针对上述情况,如果用选择排序,我们只需要在每一次中找到个子最高的那个人,直接交换到队伍的最右边,这样一来,只需要很少的交换次数就可以完成队伍的排序。

选择排序最大的优势就是省去了多余的元素交换、

七:多种编程语言实现选择排序(参考)

1:Java
public class SelectionSort implements IArraySort 
{
    @Override
    public int[] sort(int[] sourceArray) throws Exception 
    {
        int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
        // 总共要经过 N-1 轮比较
        for (int i = 0; i < arr.length - 1; i++) 
        {
            int min = i;
            // 每轮需要比较的次数 N-i
            for (int j = i + 1; j < arr.length; j++) 
            {
                if (arr[j] < arr[min]) 
                {
                    // 记录目前能找到的最小值元素的下标
                    min = j;
                }
            }

            // 将找到的最小值和i位置所在的值进行交换
            if (i != min) 
            {
                int tmp = arr[i];
                arr[i] = arr[min];
                arr[min] = tmp;
            }
        }
        return arr;
    }
}
2:JavaScript
function selectionSort(arr) 
{
    var len = arr.length;
    var minIndex, temp;
    for (var i = 0; i < len - 1; i++) 
    {
        minIndex = i;
        for (var j = i + 1; j < len; j++) 
        {
            // 寻找最小的数
            if (arr[j] < arr[minIndex]) 
            {     
                // 将最小数的索引保存
                minIndex = j;                
            }
        }
        temp = arr[i];
        arr[i] = arr[minIndex];
        arr[minIndex] = temp;
    }
    return arr;
}
3:Python
def selectionSort(arr):
    for i in range(len(arr) - 1):
        # 记录最小数的索引
        minIndex = i
        for j in range(i + 1, len(arr)):
            if arr[j] < arr[minIndex]:
                minIndex = j
        # i 不是最小数时,将 i 和最小数进行交换
        if i != minIndex:
            arr[i], arr[minIndex] = arr[minIndex], arr[i]
    return arr
4:PHP
function selectionSort($arr)
{
    $len = count($arr);
    for ($i = 0; $i < $len - 1; $i++) 
    {
        $minIndex = $i;
        for ($j = $i + 1; $j < $len; $j++) 
        {
            if ($arr[$j] < $arr[$minIndex]) 
            {
                $minIndex = $j;
            }
        }
        $temp = $arr[$i];
        $arr[$i] = $arr[$minIndex];
        $arr[$minIndex] = $temp;
    }
    return $arr;
}
5:GO
func selectionSort(arr []int) []int 
{
    length := len(arr)
    for i := 0; i < length-1; i++ 
    {
        min := i
        for j := i + 1; j < length; j++ 
        {
            if arr[min] > arr[j] 
            {
                min = j
            }
        }
        arr[i], arr[min] = arr[min], arr[i]
    }
    return arr
}

声明:

一:博文中用到的动态效果图,录取自 vx 公众号《五分钟学算法》以及《程序员小灰》,对算法感兴趣的可以关注下。

二:文章思路开源项目地址,整理人 hustcc

你的问题得到解决了吗?欢迎在评论区留言。

赠人玫瑰,手有余香,如果觉得文章不错,希望可以给个一键三连,感谢。


结束语

技术是一点一点积累的,大神也不是一天就可以达到的。原地不动就是退步,所以每天进步一点点。

最后,附上一句格言:"好学若饥,谦卑若愚",望共勉。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Allen Su

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值