【C语言】深入解析选择排序

news2024/9/22 11:42:03

文章目录

        • 什么是选择排序?
        • 选择排序的基本实现
        • 代码解释
        • 选择排序的优化
        • 选择排序的性能分析
        • 选择排序的实际应用
        • 结论

在这里插入图片描述

在C语言编程中,选择排序是一种简单且直观的排序算法。尽管它在处理大型数据集时效率不高,但由于其实现简单,常常用于教学和简单应用中。本文将详细介绍选择排序算法,包括其定义、实现、优化方法和性能分析,帮助读者深入理解这一经典算法。

什么是选择排序?

选择排序(Selection Sort)是一种基于比较的排序算法。其基本思想是每次从未排序部分中选出最小(或最大)的元素,将其放在已排序部分的末尾。重复这一过程,直到所有元素都排序完成。

选择排序的基本实现

以下是选择排序的基本实现代码:

#include <stdio.h>

// 交换两个元素的值
void swap(int* a, int* b) {
    int t = *a;
    *a = *b;
    *b = t;
}

// 选择排序函数
void selectionSort(int arr[], int n) {
    for (int i = 0; i < n-1; i++) {
        // 找到未排序部分的最小元素
        int min_idx = i;
        for (int j = i+1; j < n; j++) {
            if (arr[j] < arr[min_idx])
                min_idx = j;
        }
        // 交换最小元素和未排序部分的第一个元素
        swap(&arr[min_idx], &arr[i]);
    }
}

// 打印数组函数
void printArray(int arr[], int size) {
    for (int i = 0; i < size; i++)
        printf("%d ", arr[i]);
    printf("\n");
}

// 主函数
int main() {
    int arr[] = {64, 25, 12, 22, 11};
    int n = sizeof(arr)/sizeof(arr[0]);

    printf("未排序的数组: \n");
    printArray(arr, n);

    selectionSort(arr, n);

    printf("排序后的数组: \n");
    printArray(arr, n);

    return 0;
}
代码解释
  1. 交换函数swap

    • 用于交换两个元素的值。
  2. 选择排序函数selectionSort

    • 使用一个for循环遍历数组,每次选出未排序部分的最小元素,并将其与未排序部分的第一个元素交换。
    • 内层循环用于找到未排序部分的最小元素索引min_idx
  3. 打印数组函数printArray

    • 遍历数组并打印每个元素,便于查看排序结果。
  4. 主函数main

    • 初始化一个整数数组并计算其大小。
    • 调用selectionSort函数对数组进行排序。
    • 打印排序前后的数组。
选择排序的优化

选择排序的基本实现已经非常简单直接,但仍有一些优化方法可以稍微提升其性能:

  1. 减少交换操作

    • 在内层循环中仅记录最小元素的索引,外层循环结束后再进行交换操作,这样可以减少不必要的交换操作。

    优化代码示例:

    void selectionSort(int arr[], int n) {
        for (int i = 0; i < n-1; i++) {
            int min_idx = i;
            for (int j = i+1; j < n; j++) {
                if (arr[j] < arr[min_idx])
                    min_idx = j;
            }
            // 仅在需要时才进行交换
            if (min_idx != i)
                swap(&arr[min_idx], &arr[i]);
        }
    }
    
  2. 双向选择排序

    • 双向选择排序在每一轮中同时选出最小值和最大值,并分别放置在未排序部分的两端,从而减少排序轮数。

    优化代码示例:

    void selectionSort(int arr[], int n) {
        for (int i = 0; i < n/2; i++) {
            int min_idx = i;
            int max_idx = i;
            for (int j = i+1; j < n-i; j++) {
                if (arr[j] < arr[min_idx])
                    min_idx = j;
                if (arr[j] > arr[max_idx])
                    max_idx = j;
            }
            // 交换最小值到未排序部分的起始位置
            if (min_idx != i)
                swap(&arr[min_idx], &arr[i]);
            // 如果最大值是起始位置的元素,需要更新max_idx
            if (max_idx == i)
                max_idx = min_idx;
            // 交换最大值到未排序部分的末尾位置
            if (max_idx != n-i-1)
                swap(&arr[max_idx], &arr[n-i-1]);
        }
    }
    
选择排序的性能分析

选择排序的时间复杂度为 O ( n 2 ) O(n^2) O(n2),这是因为每次选出最小(或最大)元素都需要遍历未排序部分。无论最坏、最好还是平均情况,选择排序的时间复杂度都是 O ( n 2 ) O(n^2) O(n2)。虽然选择排序的时间复杂度较高,但由于其简单性,在处理小型数据集时仍有一定的应用价值。

选择排序的空间复杂度为 O ( 1 ) O(1) O(1),因为它只需要常数级别的额外空间来存储临时变量。选择排序是一个不稳定的排序算法,因为相同元素的相对位置可能会改变。

选择排序的实际应用

选择排序由于其简单性和易实现性,在以下几种情况下非常有用:

  1. 教学和演示

    • 选择排序算法简单直观,非常适合作为初学者学习排序算法的入门教材。
  2. 小型数据集

    • 在处理小型数据集时,选择排序的性能足够,而且实现简单。
  3. 需要简单实现的场景

    • 选择排序的实现代码简洁明了,适合在需要快速实现排序功能的场景中使用。
结论

选择排序是C语言中一种简单且直观的排序算法,其实现简单且易于理解。尽管选择排序的效率较低,但通过减少不必要的交换操作和双向选择排序等方法,可以在一定程度上提升其性能。在学习和使用选择排序时,了解其优缺点以及适用场景,能够帮助我们更好地选择和使用排序算法。希望本文能帮助读者深入理解选择排序,并在实际编程中灵活应用。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

IT产品研发全生命周期【详细说明】

阶段步骤任务负责人产品管理用户故事收集和理解用户需求&#xff0c;创建用户故事产品经理需求分类分类用户故事&#xff0c;组织和优先级排序需求经理可行性分析评估需求的技术可行性与实现难度研发经理需求转换将需求转化为具体的产品特性或功能要求需求经理需求管理创建需求…

【机器学习】机器学习与语音识别的融合应用与性能优化新探索

文章目录 引言第一章&#xff1a;机器学习在语音识别中的应用1.1 数据预处理1.1.1 数据去噪1.1.2 数据归一化1.1.3 特征提取 1.2 模型选择1.2.1 隐马尔可夫模型1.2.2 循环神经网络1.2.3 长短期记忆网络1.2.4 Transformer 1.3 模型训练1.3.1 梯度下降1.3.2 随机梯度下降1.3.3 Ad…

Three.JS 使用RGBELoader和CubeTextureLoader 添加环境贴图

导入RGBELoader模块&#xff1a; import { RGBELoader } from "three/examples/jsm/loaders/RGBELoader.js"; 使用 addRGBEMappingk(environment, background,url) {rgbeLoader new RGBELoader();rgbeLoader.loadAsync(url).then((texture) > {//贴图模式 经纬…

基于Linux的USB-wifi配置流程

目录 内核配置 配置 CFG80211 配置usb 配置 Netlink 配置DHCP 工作流程 1.连接到无线网络 2.设置网络接口&#xff1a; 3.验证连接&#xff1a; 4. 接收数据&#xff1a; 最近daisy一直忙活这个linux的wifi驱动和bluze蓝牙驱动&#xff0c;相比较蓝牙&#xff0c;WiFi的驱动和内…

【ARMv8/v9 GIC- 700 系列 2 -- GIC-700 上电控制寄存器 GICR_PWRR】

请阅读【ARM GICv3/v4 实战学习 】 文章目录 GIC-700 上电GICR_PWRR 寄存器字段介绍GICR_PWRR 功能说明GICR_PWER 代码配置GICR_PWRR 使用场景GICR_PWRR 注意事项GIC-700 上电 GICR_PWRR(功耗寄存器)是ARM GICv4架构中用于控制GIC-700是否可以关闭电源的寄存器。它通过几个位…

【日记】我倒是想穿可爱的 JK 小裙子,可惜我是哥布林……(704 字)

正文 中午给三盆植物换水&#xff0c;惊叹于文竹的根。长得之长&#xff0c;都能在花盆里盘几圈了。而且我好像有一段时间没换水了&#xff0c;花盆的水中和盆底有了些绿藻。虽然不知道好不好&#xff0c;但我还是清掉了&#xff0c;摸起来黏黏的。而且我也总是觉得单位的水&am…

InceptionV3代码实现(Pytorch)

文章目录 Inception介绍InceptionV3代码实现第一步&#xff1a;定义基础卷积模块第二步&#xff1a;定义Inceptionv3模块InceptionAInceptionBInceptionCInceptionDInceptionE 第三步&#xff1a;定义辅助分类器InceptionAux第四步&#xff1a;搭建GoogLeNet网络第五步*&#x…

算法力扣刷题记录 五十二【617.合并二叉树】

前言 二叉树篇&#xff0c;继续。 记录 五十二【617.合并二叉树】 一、题目阅读 给你两棵二叉树&#xff1a; root1 和 root2 。 想象一下&#xff0c;当你将其中一棵覆盖到另一棵之上时&#xff0c;两棵树上的一些节点将会重叠&#xff08;而另一些不会&#xff09;。你需要…

HCIE-AI大模型直通车火热报名中

第一阶段&#xff1a;HCIA-AI Solution Architect&#xff08;直播&#xff0c;39课时&#xff09; 该阶段详细介绍 AI 大模型所需基础技术栈&#xff0c;包含深度学习基础、计算机视觉技术、自然语言处理技术、华为开源深度学习框架 MindSpore、注意力制、Transformer 架构&am…

【雷丰阳-谷粒商城 】【分布式高级篇-微服务架构篇】【22】【RabbitMQ】

持续学习&持续更新中… 守破离 【雷丰阳-谷粒商城 】【分布式高级篇-微服务架构篇】【22】【RabbitMQ】 Message Queue 消息队列异步处理应用解耦流量控制 消息中间件概念RabbitMQ概念MessagePublisherExchangeQueueBindingConnectionChannelConsumerVirtual HostBroker图…

汽车免拆诊断案例 | 卡罗拉急加速抖动故障排除

车型信息 2017年改款卡罗拉&#xff0c;排量1.2T&#xff0c;行驶里程48800公里。 故障现象 车辆不管在什么状态下&#xff0c;只要是平缓加速&#xff0c;都不会有抖动。车辆静止时&#xff0c;急加速时&#xff0c;也不会有抖动。但是车速达40公里/小时以上&#xff0c;急加…

【Linux】基础I/O——理解ext2文件系统

我们到现在为止讲的都是打开的文件。现在我们讲讲没有打开的文件 如果一个文件没有被打开&#xff0c;那它就是在磁盘中被存储的&#xff0c;我们就要关心路径问题&#xff0c;存储问题&#xff0c;文件获取问题&#xff0c;那么操作系统是怎么处理这些问题的&#xff1f;不急…

python如何输入矩阵

使用numpy创建矩阵有2种方法&#xff0c;一种是使用numpy库的matrix直接创建&#xff0c;另一种则是使用array来创建。 首先导入numpy&#xff1a; &#xff08;1&#xff09;import numpy &#xff08;2&#xff09;from numpy import * &#xff08;3&#xff09;import …

MYSQL调优详解:案例解析(第40天)

系列文章目录 一、数据库设计优化 二、查询优化 三、架构优化 四、其他优化策略 五、优化案例解析 文章目录 系列文章目录前言一、数据库设计优化二、查询优化三、架构优化四、其他优化策略五、优化案例解析案例一&#xff1a;优化SELECT查询案例二&#xff1a;使用索引案例三…

Quartus II 13.1添加新的FPGA器件库

最近需要用到Altera的一款MAX II 系列EPM240的FPGA芯片&#xff0c;所以需要给我的Quartus II 13.1添加新的器件库&#xff0c;在此记录一下过程。 1 下载所需的期间库 进入Inter官网&#xff0c;&#xff08;Altera已经被Inter收购&#xff09;https://www.intel.cn/content…

Java 反射机制:概念、用途与示例

个人名片 &#x1f393;作者简介&#xff1a;java领域优质创作者 &#x1f310;个人主页&#xff1a;码农阿豪 &#x1f4de;工作室&#xff1a;新空间代码工作室&#xff08;提供各种软件服务&#xff09; &#x1f48c;个人邮箱&#xff1a;[2435024119qq.com] &#x1f4f1…

C语言第5天作业 7月16日

目录 1.求1000以内所有的质数。 2.有1、2、3、4个数字&#xff0c;能组成多少个互不相同且无重复数字的三位数&#xff1f;都是多少&#xff1f; 3.猴子吃桃问题 4.判断最大值 1.求1000以内所有的质数。 质数&#xff1a;只能够1和它本身整除 #include <stdio.h> in…

Cxx Primer-Chap4

表达式可以没有操作符&#xff0c;但一定有操作数&#xff1a;理解表达式中含有多个操作符时涉及操作符的优先级、关联性以及操作数的计算顺序&#xff1a;如果操作符需要的操作数类型不同&#xff0c;则会发生一些默认的类型转换&#xff1a;什么叫Overloaded Operators&#…

Python 合并两个有序数组

Python 合并两个有序数组 正文 正文 题目说明如下&#xff1a; 这里我们直接让 nums1 的后 n 个数等于 nums2 数组&#xff0c;然后对 nums1 数组整体进行排序即可。 class Solution:def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:"…

Linux中的fork函数及.PHONY

cat fork.c #include<stdio.h> #include<unistd.h> int main() {printf("fork()函数执行前&#xff0c;进程为: %d\n",getpid());pid_t retfork();sleep(1);if(ret>0)printf("我是父进程&#xff0c;我的id为: %d,子进程为 %d\n",getpid(),…