跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C算法

选择排序算法详解:原理、代码与优化

选择排序是一种基础排序算法,核心思想是每轮从未排序序列中选出最小元素置于已排序序列末尾。详细解析了该算法的工作原理及逐步执行过程,提供了 C 语言代码实现,并针对效率问题介绍了双向选择排序优化方案,通过同时确定最大值和最小值减少遍历次数。最后分析了算法的时间复杂度为 O(n^2),空间复杂度为 O(1),适用于数据量较小场景。

禅心发布于 2026/3/15更新于 2026/6/1416 浏览
选择排序算法详解:原理、代码与优化

选择排序概述

选择排序(Selection Sort)是一种基础且直观的排序算法。它的核心逻辑很简单:每一轮遍历从未排序的序列中选出最小(或最大)的元素,将其放到已排序序列的末尾。

实现思路遵循由局部到整体:先排好一个元素,再处理多个,直到整个数组有序。

工作原理演示

以升序排序为例,整个过程可以拆解为以下步骤:

  1. 初始化:假设数组前部分是已排序的,后部分是未排序的。初始时,已排序部分为空。
  2. 寻找极值:遍历未排序部分,找出其中的最小值。
  3. 交换位置:将找到的最小值与未排序部分的第一个元素交换。
  4. 重复迭代:缩小未排序部分的范围,重复上述步骤,直到整个数组有序。

选择排序动图

执行过程示例

假设待排序数组为:[3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48]

  • 第一轮:在未排序部分 [3, 44, ...] 中找到最小值 2。将 2 与首位 3 交换。数组变为 [2, 44, 38, 5, 47, 15, 36, 26, 27, 3, 46, 4, 19, 50, 48]。
  • 第二轮:在剩余未排序部分 [44, 38, ...] 中找到最小值 3。将 3 与首位 44 交换。数组变为 [2, 3, 38, 5, 47, 15, 36, 26, 27, 44, 46, 4, 19, 50, 48]。
  • 第三轮:找到最小值 4,与首位 38 交换。数组变为 [2, 3, 4, 5, 47, 15, 36, 26, 27, 44, 46, 38, 19, 50, 48]。
  • 第四轮:最小值是 5,它已经在正确位置,无需交换。
  • 后续轮次:依次确定 15, 19, 26, 27, 36, 38, 44, 46, 47, 48 的位置。

经过多轮筛选与交换,最终得到有序数组:[2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 48, 50]。

代码实现

下面是基于 C 语言的基础选择排序实现。注意,这里假设存在一个 Swap 辅助函数用于交换两个整数的地址。

void SelectSort(int* a, int n) {
    // i 控制排序趟数,需要 n-1 趟才能使得待排数组有序
     ( i = ; i < n - ; i++) {
        
         min_index = i;
        
        
         ( j = i + ; j < n; j++) {
             (a[j] < a[min_index]) {
                min_index = j;
            }
        }
        
        
         (min_index != i) {
            Swap(&a[i], &a[min_index]);
        }
    }
}
for
int
0
1
// 默认最小值下标为未排序元素中的第一个
int
// j 控制寻找最小值的过程,从 i+1 开始比较
for
int
1
if
// 如果找到了更小的元素,则交换
if

优化方案:双向选择排序

基础版本每轮仅确定一个最小值。我们可以优化这一过程,让每轮同时确定最大值和最小值:最小值放前端,最大值放后端。这样可以将排序趟数减半,显著提升效率。

void SelectSortOptimized(int* a, int n) {
    int begin = 0;
    int end = n - 1;
    
    while (begin < end) {
        int mini = begin;
        int maxi = begin;
        
        // 遍历未排序区间 [begin, end]
        for (int i = begin + 1; i <= end; i++) {
            if (a[i] < a[mini]) mini = i;
            if (a[i] > a[maxi]) maxi = i;
        }
        
        // 交换最小值到 begin 位置
        Swap(&a[begin], &a[mini]);
        
        // 特殊情况处理:如果最大值原本就在 begin 位置
        // 交换后最大值被换到了 mini 位置,需更新 maxi 下标
        if (maxi == begin) {
            maxi = mini;
        }
        
        // 交换最大值到 end 位置
        Swap(&a[end], &a[maxi]);
        
        begin++;
        end--;
    }
}

一般情况下的双端选择过程如下:

双向选择排序示意图

特殊情况(最大值在起始位置):

特殊情况处理

复杂度分析

时间复杂度

无论最好、最坏还是平均情况,选择排序都需要进行固定次数的比较。

  • 第 1 趟:从 n 个元素里找最小值,比较 n−1 次
  • 第 2 趟:从剩下的 n-1 个元素里找最小值,比较 n−2 次
  • ...
  • 总比较次数:(n−1) + (n−2) + ⋯ + 1 = n(n−1)/2

因此,时间复杂度为 O(n²)。

空间复杂度

选择排序是原地排序算法,只需要常数个辅助变量(如保存当前最小值下标等),不需要额外开辟与 n 成比例的空间。

因此,空间复杂度为 O(1)。

总结

选择排序虽然简单,但效率较低,适合数据量较小或对稳定性无要求的场景。通过双向优化的思路,我们可以在不改变时间复杂度的前提下减少实际交换次数,提升运行性能。在实际工程中,面对大规模数据时,通常会优先考虑快速排序或归并排序等更高效算法。

目录

  1. 选择排序概述
  2. 工作原理演示
  3. 执行过程示例
  4. 代码实现
  5. 优化方案:双向选择排序
  6. 复杂度分析
  7. 时间复杂度
  8. 空间复杂度
  9. 总结
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • Python 闭包深度解密:当变量捕获遇见 nonlocal 的优雅与陷阱
  • OpenCV 功能特性与依赖关系配置
  • Python 破解行为检测与浏览器指纹反爬:从原理到实战
  • Promise.resolve 方法详解
  • 物业 ERP 系统技术架构解析:低代码与 AI 应用实践
  • Vue3 + PlayCanvas 实战:3D 地图自由巡视闯关游戏开发
  • 生物细胞学在 AI 时代的最新进展
  • 文心一言大模型使用指南:指令编写与进阶应用
  • 数字图像处理与 FPGA 实现:搭建算法与硬件思维的桥梁
  • 使用 Gitee 与 PicGo 搭建 Markdown 图床完整指南
  • 国内股票分析 AI 开源项目精选:GitHub 热门榜单
  • Java 后端面试经验汇总:京东与有赞
  • 流式输出详解:后端生成与前端渲染实现
  • 滑动窗口算法:找到字符串中所有字母异位词
  • Qt C++ 无边框窗口开发:自定义标题栏、圆角及阴影实现
  • 计算机网络:WebSocket 如何实现全双工通信
  • OpenClaw WebSocket Channel 开发实战:从零打造自定义 AI 通信通道
  • Web 服务与 I/O 模型
  • 扩散模型(Diffusion Model)原理与图像生成实战
  • Java 大数据在智能家居能源消耗趋势预测与节能策略优化中的应用

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online