IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 排序算法-选择排序(C语言) -> 正文阅读

[数据结构与算法]排序算法-选择排序(C语言)

选择排序,简单粗暴直观的排序算法。

一个长度为N的序列num[N],分为有序部分和无序部分

第一次,num[0]~num[N-1]是无序部分,从这N个数中选出最小的数,放在序列的第一个位置,

此时,num[0]是有序部分,num[1]~num[N]是无序部分

第二次,num[0]是有序部分,num[1]~num[N]是无序部分,从N-1个数中选出最小的数,放在序列的第二个位置,

此时,num[0]~num[1]是有序部分,num[2]~num[N]是无序部分

如此进行下去,整个序列最终为有序(顺序)序列

代码:

#include<stdio.h>
#define N 10
void selectsort(int *num , int length )
{ 
    int i ;
    int j;
    int temp;//中间变量,供交换值的时候使用
    for(i = 0;i < length ; i ++)//假设无序序列的第一个元素num[i]为最小值
    {   
        for(j = i+1 ; j < length ;j++)//遍历最小值后面的所有元素(num[i+1]~num[length-1])
        {
            if(num[i] > num[j])//若找到比最小值num[i]还要小的元素,则与原来的最小值元素交换值
            {
                temp = num[i];
                num[i] = num[j];
                num[j] = temp;
            }
        }
    }
}

int main()
{
    int num[N] = {9,8,7,6,5,4,3,2,1,0};
    selectsort(num , N);
    for(int i=0; i < N;i++)
    {
        printf("%d ",num[i]);
    }
    printf("\n");
    return 0;
}

运行结果

看一下程序细节

时间复杂度

第一次需要遍历N-1个元素,第二次需要遍历N-2个元素······

\large \sum_{i=1}^{n-1}(n-i)=n-1+ n-2 +\cdot \cdot \cdot +1 = \frac{n(n-1)}{2}

所以时间复杂度是)O(N^2)

然而,细想一下,选择排序,每一趟遍历无序部分,却只为了找到那个最小的数,效率太低(老子辛辛苦苦在无序序列兜了一圈,只找一个最小值,这哪行,哪像计算机人搜搜扣扣的精神(又扣时间又扣空间))

于是,赶一只羊也是赶,赶两只羊也是赶。我们跑一趟无序序列,把最小值和最大值都找出来。

代码:

#include<stdio.h>
#define N 10
#include<time.h>
void  swap(int *a,int *b)//函数作用,交换a和b的值
{
    int temp ;
    temp = *a;
    *a = *b;
    *b = temp;
}
void selectsort(int *num ,int n)
{   
    int start = 0;//无序部分的第一个元素
    int end = N-1;//无序部分的最后一个元素
    while(start < end)
    {
        int min_index = start;//最小值元素的下标
        int max_index = end;//最大值元素的下标
        int i = 0;
        for(i = start;i<=end;i++)//遍历无序序列
        {
            if(num[i] < num[min_index])
                min_index = i;//记录无序序列最小值元素的下标
            if(num[i] > num[max_index])
                max_index = i; //记录无序序列最大值元素的下标
        }
        swap(&num[start],&num[min_index]);//将找到的最小值放在序列开头
        //错误语句实例 swap(&num[end],&num[max_index]);
        //将找到的最大值放在序列末尾,看似合情合理,但在极端情况下与上一句语句是矛盾的
        //本例就属于极端情况,此处挖一个坑
       
        if(start == max_index)//极端情况,当最大值位于序列开头,要被最小值替换
        {
            max_index = min_index;
        }
        start++;//缩小无序序列长度,因为有序序列变长了
        end--;

        //细节演示
        // for(int i = 0;i<N;i++)
        // {
        // printf("%d ",num[i]);
        // }
        // printf("\n");

    }
}

int main()
{   
    int num[N] = {9,8,7,6,5,4,3,2,1,0};
    selectsort(num,N);
    for(int i = 0;i<N;i++)
    {
        printf("%d ",num[i]);
    }
    printf("\n");
    return 0;
}

运行结果:

?

程序细节:

?对比单向选择排序算法,双向选择排序虽然时间复杂都仍然是O(N^2),但是效率优化了50%左右

?填坑:

我们需要排序的序列是num[10] = {9,8,7,6,5,4,3,2,1,0}

先来看一下错误代码

?错误细节,每一次遍历序列的变化

可以看到?,第一次遍历,最小值下标是9,最大值下标是0,处理过程是将num[min_index]放在序列开头,num[max_index]放在序列末尾,即num[0] <——>num[9],即num[0]和num[9]只需要一次换值;

但是因为执行两次swap()(换值函数),相当于原来序列并没有发生变化

在以后的遍历中,也是这种情况,所以最终结果是序列没有任何变化,也就不难理解为何代码要做如下处理


正确代码

?正确细节,每一次遍历序列的变化

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-11-23 12:37:09  更:2021-11-23 12:37:22 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 12:25:33-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码