【数据结构】直接选择排序(你知道最不常用的排序算法有哪些吗?)

在这里插入图片描述

👦个人主页:Weraphael
✍🏻作者简介:目前正在学习c++和算法
✈️专栏:数据结构
🐋 希望大家多多支持,咱一起进步!😁
如果文章有啥瑕疵
希望大佬指点一二
如果文章对你有帮助的话
欢迎 评论💬 点赞👍🏻 收藏 📂 加关注😍


目录

  • 一、基本思想
  • 二、传统算法思路
  • 三、传统代码实现
  • 四、优化版本思路
  • 五、优化版本代码实现
  • 六、特性总结

一、基本思想

在这里插入图片描述

基本思想:每一次从原数组的元素中选出一个最大/最小的元素,放在序列的起始位置(选最大还是最小看排的是升序还是降序),直至全部待排序的数据全部排完。

二、传统算法思路

以排列升序为例

  1. 在元素集合array[0]--array[n-1]中选择随机选择一个数据元素。假设array[0]是最小的(注意是假设)
  2. 然后再从元素集合array[1]--array[n-1]遍历,如果集合中还有元素比array[0]小,则更新。
  3. 重复上述步骤,直到集合剩余1个元素

三、传统代码实现

#include <stdio.h>

void Swap(int *x, int *y)
{
    int t = *x;
    *x = *y;
    *y = t;
}

void select_sort(int a[], int n)
{
    // 1. 规划区间
    int l = 0, r = n - 1;

    // 5. 直到集合剩余一个元素为止
    while (l < r)
    {
        // 2. 假设最小值是a[0],下标是l = 0
        int Min = l;

        // 3. 遍历区间[l + 1, r]for (int i = l + 1; i <= r; i++)
        {
            if (a[i] < a[Min])
            {
                // 更新最小值下标
                Min = i;
            }
        }

        // 4. 当循环结束后,直接让下标为l和下标为Min直接交换
        Swap(&a[l], &a[Min]);

        l++;
    }
}

int main()
{
    int a[] = {10, 1, 6, 9, 4, 7, 2, 3, 8, 5};
    int aSize = sizeof(a) / sizeof(a[0]);

    select_sort(a, aSize);

    for (int i = 0; i < aSize; i++)
    {
        printf("%d ", a[i]);
    }
    printf("\n");

    return 0;
}

【结果展示】

在这里插入图片描述

四、优化版本思路

  1. 定义leftright分别表示数组的头和尾
  2. 每次遍历left~right区间里的元素,找到最小的数与left为下标的元素进行交换;同理,找到最大的元素与以right为下标的元素进行交换,完成交换后分别缩小leftright之间的范围
  3. 重复上述步骤,直到集合剩余一个元素为止

注意:这里会有一个大家忽略的问题:重叠问题

在这里插入图片描述

如上图所示,a[l] a[MinIdx]交换后,此时maxIdx指向的元素就是最小值了,再对a[r]a[MaxIdx]就会出错,因此,再次交换之前需要将MaxIdx指向MinIdx

五、优化版本代码实现

#include <stdio.h>

void Swap(int *x, int *y)
{
    int t = *x;
    *x = *y;
    *y = t;
}

void select_sort(int a[], int n)
{
    // 1. 规定区间
    int l = 0, r = n - 1;

    // 直到集合剩余一个元素为止
    while (l < r)
    {
        // 2. 假设最大值和最小值都是下标为0的元素
        int MinIdx = l, MaxIdx = l;

        // 3. 遍历[l + 1, r]
        for (int i = l + 1; i <= r; i++)
        {
            // 分别更新最大值和最小值的下标
            if (a[i] > a[MaxIdx])
            {
                MaxIdx = i;
            }
            if (a[i] < a[MinIdx])
            {
                MinIdx = i;
            }
        }
        // 当for循环结束后,说明已经找到区间内的最大值和最小值
        // 直接分别和下标为l、r交换即可
        Swap(&a[l], &a[MinIdx]);

        // 可能存在left和Max重叠
        if (l == MaxIdx)
        {
            MaxIdx = MinIdx;
        }
        Swap(&a[r], &a[MaxIdx]);

        // 更新区间
        l++;
        r--;
    }
}

int main()
{
    int a[] = {10, 1, 6, 9, 4, 7, 2, 3, 8, 5};
    int aSize = sizeof(a) / sizeof(a[0]);

    select_sort(a, aSize);

    for (int i = 0; i < aSize; i++)
    {
        printf("%d ", a[i]);
    }
    printf("\n");

    return 0;
}

【结果展示】

在这里插入图片描述

六、特性总结

  • 时间复杂度

首先先来分析传统版本,每次排好一个数是n - 1次,第二个数是n - 2次…,是一个等差数列。因此时间复杂度是O(N2)

同理的,优化版本排好一个数是n - 2次,第二个就是n - 4次…,同样也是一个等差数列。因此时间复杂度还是O(N2)

总之,直接选择排序效率极低,实际中很少使用。

  • 空间复杂度:O(1)
  • 稳定性:不稳定

那么如果对一个有序序列进行选择排序(使用优化版),它的效率又会是如何呢?我们可以来测试一下

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void Swap(int* x, int* y)
{
    int t = *x;
    *x = *y;
    *y = t;
}

// 优化版
void select_sort(int a[], int n)
{
    // 1. 规定区间
    int l = 0, r = n - 1;

    // 直到集合剩余一个元素为止
    while (l < r)
    {
        // 2. 假设最大值和最小值都是下标为0的元素
        int MinIdx = l, MaxIdx = l;

        // 3. 遍历[l + 1, r]
        for (int i = l + 1; i <= r; i++)
        {
            // 分别更新最大值和最小值的下标
            if (a[i] > a[MaxIdx])
            {
                MaxIdx = i;
            }
            if (a[i] < a[MinIdx])
            {
                MinIdx = i;
            }
        }
        // 当for循环结束后,说明已经找到区间内的最大值和最小值
        // 直接分别和下标为l、r交换即可
        Swap(&a[l], &a[MinIdx]);

        // 可能存在left和Max重叠
        if (l == MaxIdx)
        {
            MaxIdx = MinIdx;
        }
        Swap(&a[r], &a[MaxIdx]);

        // 更新区间
        l++;
        r--;
    }
}

int main()
{
    srand(time(0));
    const int N = 100000; // 十万测试数据
    int* a1 = (int*)malloc(sizeof(int) * N);

    for (int i = 0; i < N; i++)
    {
        a1[i] = rand();
    }
    // 先排好序
    select_sort(a1, N);

    int begin = clock();
    select_sort(a1, N);
    int end = clock();

    printf("快速选择排序:%d\n", end - begin);
    return 0;
}

【运行结果】

在这里插入图片描述

需要差不多9秒

因此,直接选择排序是一个鸡肋的排序算法

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/151484.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

AI创作系统ChatGPT网站源码+详细搭建部署教程+支持DALL-E3文生图/支持最新GPT-4-Turbo-With-Vision-128K多模态模型

一、AI创作系统 SparkAi创作系统是基于OpenAI很火的ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如…

OpenSign:安全可靠的电子签名解决方案 | 开源日报 No.76

microsoft/Web-Dev-For-Beginners Stars: 71.5k License: MIT 这个开源项目是一个为期 12 周的全面课程&#xff0c;由微软云倡导者团队提供。它旨在帮助初学者掌握 JavaScript、CSS 和 HTML 的基础知识。每一节都包括预习和复习测验、详细的书面指南、解决方案、作业等内容。…

JavaScript学习_01——JavaScript简介

JavaScript简介 JavaScript介绍 JavaScript是一种轻量级的脚本语言。所谓“脚本语言”&#xff0c;指的是它不具备开发操作系统的能力&#xff0c;而是只用来编写控制其他大型应用程序的“脚本”。 JavaScript 是一种嵌入式&#xff08;embedded&#xff09;语言。它本身提供…

第三篇 《随机点名答题系统》——人员管理详解(类抽奖系统、在线答题系统、线上答题系统、在线点名系统、线上点名系统、在线考试系统、线上考试系统)

目录 1.功能需求 2.数据库设计 3.流程设计 4.关键代码 4.1.人员分组 4.1.1数据请求示意图 4.1.2添加组别&#xff08;login.php&#xff09;数据请求代码 4.1.3编辑组别&#xff08;login.php&#xff09;数据请求代码 4.1.4加入分组&#xff08;login.php&#xff09…

【附安装包】3ds Max2023安装教程

软件下载 软件&#xff1a;3ds Max版本&#xff1a;2023语言&#xff1a;简体中文大小&#xff1a;6.85G安装环境&#xff1a;Win11/Win10/Win8/Win7硬件要求&#xff1a;CPU3GHz 内存16G(或更高&#xff09;下载通道①百度网盘丨64位下载链接&#xff1a;https://pan.baidu.c…

Spring6(二):IoC容器

文章目录 3. 容器&#xff1a;IoC3.1 IoC容器3.1.1 控制反转&#xff08;IoC&#xff09;3.1.2 依赖注入3.1.3 IoC容器在Spring的实现 3.2 基于XML管理Bean3.2.1 搭建子模块spring6-ioc-xml3.2.2 获取bean方式一&#xff1a;根据id获取方式二&#xff1a;根据类型获取方式三&am…

python自动化测试面试题

1、自动化代码中,用到了哪些设计模式? 单例设计模式工厂模式PO设计模式数据驱动模式面向接口编程设计模式 2、什么是断言( Assert) ? 断言Assert用于在代码中验证实际结果是不是符合预期结果&#xff0c;如果测试用例执行失败会抛出异常并提供断言日志 3、什么是web自动化测…

Lobatto Quadrature

See https://mathworld.wolfram.com/LobattoQuadrature.html

前端面试hr经常会问的问题

文章目录 前言1.自我介绍2.为什么你要离职&#xff1f;3.工作经历4.职业规划5.优点、缺点6.还有什么要问的 总结 前言 这里记录了一些面试中hr或者项目负责人经常会问的一些问题&#xff0c;可以提前参考参考&#xff0c;想想该怎么回答&#xff0c;为之后的面试做好准备&…

【数据处理】Python:实现求条件分布函数 | 求平均值方差和协方差 | 求函数函数期望值的函数 | 概率论

猛戳订阅&#xff01; &#x1f449; 《一起玩蛇》&#x1f40d; &#x1f4ad; 写在前面&#xff1a;本章我们将通过 Python 手动实现条件分布函数的计算&#xff0c;实现求平均值&#xff0c;方差和协方差函数&#xff0c;实现求函数期望值的函数。部署的测试代码放到文后了&…

一加手机全球摄影展深圳开展 历年获奖作品齐登场

11 月 18 日至 12 月 3 日&#xff0c;一加手机将携手国际摄影奖&#xff08;International Photography Awards&#xff0c;以下简称IPA&#xff09;&#xff0c;在深圳市南山区海岸城购物中心举办一加手机全球摄影展&#xff08;OnePlus Global Photography Exhibition&#…

手机数据恢复应用程序有哪些?手机数据恢复免费软件排名TOP 9

一些免费的手机数据恢复应用程序和软件有付费版本。 如果您想要高功能&#xff0c;请选择付费版本&#xff0c;如果您不想要那么多功能&#xff0c;或者如果您目前不需要它&#xff0c;请选择免费版本。 手机数据恢复免费软件排名TOP 9 ​1. 奇客数据恢复 ​奇客数据恢复是一款…

PyTorch技术和深度学习——四、神经网络训练与优化

文章目录 1.神经网络迭代概念1&#xff09;训练误差与泛化误差2&#xff09;训练集、验证集和测试集划分3&#xff09;偏差与方差 2.正则化方法1&#xff09;提前终止2&#xff09;L2正则化3&#xff09;Dropout 3.优化算法1&#xff09;梯度下降2&#xff09;Momentum算法3)RM…

052-第三代软件开发-系统监测

第三代软件开发-系统监测 文章目录 第三代软件开发-系统监测项目介绍系统监测 关键字&#xff1a; Qt、 Qml、 cpu、 内存、memory 项目介绍 欢迎来到我们的 QML & C 项目&#xff01;这个项目结合了 QML&#xff08;Qt Meta-Object Language&#xff09;和 C 的强大功…

asp.net core mvc 之 依赖注入

一、视图中使用依赖注入 1、core目录下添加 LogHelperService.cs 类 public class LogHelperService{public void Add(){}public string Read(){return "日志读取";}} 2、Startup.cs 文件中 注入依赖注入 3、Views目录中 _ViewImports.cshtml 添加引用 4、视图使用…

Go语言常用命令详解(一)

文章目录 前言常用命令go build示例参数说明 go test示例参数说明 go run示例参数说明 go clean示例参数介绍 总结写在最后 前言 Go语言是一种开源的编程语言&#xff0c;由Google开发并于2009年首次发布。它以其简洁、高效和并发性能而备受开发者的喜爱。作为一门相对年轻的语…

C进阶---自定义类型:结构体、枚举、联合

目录 一、前言 二、结构体 2.1结构体的声明 2.2特殊的声明 2.3结构体的自引用 2.4结构体变量的定义和初始化 2.5结构体内存对齐 2.6修改默认对齐数 2.7结构体传参 三、位段 3.1什么是位段 3.2位段的内存分配 3.3位段的跨平台问题 3.4位段的应用 四、枚…

【ML】欠拟合和过拟合的一些判别和优化方法(吴恩达机器学习笔记)

吴恩达老师的机器学习教程笔记 减少误差的一些方法 获得更多的训练实例——解决高方差尝试减少特征的数量——解决高方差尝试获得更多的特征——解决高偏差尝试增加多项式特征——解决高偏差尝试减少正则化程度 λ——解决高偏差尝试增加正则化程度 λ——解决高方差 什么是…

Spring-IoC与DI入门案例

IoC入门案例 IoC入门案例思路分析 管理什么&#xff1f;&#xff08;Service与Dao&#xff09;如何将被管理的对象告知IoC容器&#xff1f;&#xff08;配置&#xff09;被管理的对象交给IoC容器&#xff0c;如何获取到IoC容器&#xff1f;&#xff08;接口&#xff09;IoC容…

【Java 进阶篇】JQuery 动画:为页面添彩的魔法

在现代的Web开发中&#xff0c;用户体验的提升是至关重要的一环。而动画作为页面交互中的重要组成部分&#xff0c;更是为用户带来了全新的感官体验。本篇博客将深入探讨 JQuery 中动画的应用&#xff0c;带你进入一个充满活力的前端世界。 前言 动画是网页设计的一种重要手段…