排序剑谱之选择篇

八大排序------选择排序

本篇文章我们一起来了解一下八大排序中的选择排序
与冒泡排序一样选择排序也是我们初学C语言所了解到的比较基础的排序

选择排序的逻辑思想

现在让我们一起来了解一下选择排序的逻辑思想
选择排序的基本思想:第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后再从剩余的未排序元素中寻找到最小(大)元素,然后放到已排序的序列的末尾。以此类推,直到全部待排序的数据元素的个数为零。
简单来说就是:

重复(元素个数-1)次

  把第一个没有排序过的元素设置为最小值

    遍历每个没有排序过的元素

        如果元素 < 现在的最小值

           将此元素设置成为新的最小值

    将最小值和第一个没有排序过的位置交换

通过后续的学习我们会发现选择排序是不稳定的排序方法

选择排序的图文详解

我们就通过一个简单的例子来充分了解一下选择排序是如何实现的。
我们先建立一个数组{27,38,12,39,27,16},。

在这里插入图片描述
第一步: 把第一个没有排序过的元素设置为最小值
在这里插入图片描述
第二步: 遍历每个没有排序过的元素,如果元素 < 现在的最小值, 将此元素设置成为新的最小值。
在这里插入图片描述

第三步:将最小值和第一个没有排序过的位置交换。
在这里插入图片描述
至此我们的第一次循环结束,数组中最小的数排在了第一位
在这里我们需要注意的是 12 已经排在了应该在的位置,所以下次排序从 38 开始。
我们只需要重复 5 次即可将原数组有序排列。
当有 n 个数时我们需要将上述循环重复(n - 1)次

选择排序的代码实现

到这里我们也了解了选择排序逻辑思想,下面让我们来一起看一下选择排序的代码实现

#include<stdio.h>

void Selectsort(int* p, int n)
{
    int i, j;
    int min = 0;
    for (i = 0;i < n - 1;i++)    //排序次数 n - 1 次
    {
        min = i;
        for (j = i + 1;j < n;j++)
        {
            if (p[j] < p[min])
            {
                min = j;      //记录交换的元素下标值
            }
        }
        if (i != min)
        {
            int temp = p[i];
            p[i] = p[min];
            p[min] = temp;
        }
    }
}
void  SelectPrint(int a[8])//输出函数
{
    int i = 0;
    for (i = 0;i < 8;i++)
    {
        printf("%d ", a[i]);
    }
    printf("\n");
}

int main()
{
    int a[5] = { 0 };
  
    for (int i = 0;i < 5;i++)
    {
        scanf("%d", &a[i]);
    }

    Selectsort(a, 5);
    SelectPrint(a);

    return 0;
}

现在我们输入一下例子得到如下结果:
在这里插入图片描述

选择排序的复杂度

从简单选择排序的过程来看,它最大的特点就是交换移动数据次数相当少,这样也就节约了相应的时间。

分析它的时间复杂度发现,无论最好最差的情况,其比较次数都是一样的多,第i趟排序需要进行n-i次关键字的比较,因而需要比较 n(n−1)/2次

而对于交换次数而言,当最好的时候,交换为0次,最差的时候,也就初始降序时,交换次数为n-1次,基于最终的排序时间是比较与交换的次数总和,因此,总的时间复杂度依然为O(n2)。

应该说,尽管与冒泡排序同为O(n2),但选择排序的性能上还是要略优于冒泡排序

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值