当前位置: 首页 > news >正文

CSP-J/S冲奖第20天:选择排序

一、什么是选择排序?

  • 定义:选择排序是一种简单直观的排序算法,每次从未排序部分选择最小(或最大)的元素,放到已排序部分的末尾。

  • 类比:就像整理书架时,每次都从剩下的书中找到最小的那本,放在正确的位置。

  • 特点
    • 时间复杂度为 (O(n^2)),适合小规模数据。

    • 交换次数少,性能比冒泡排序略优。


二、选择排序的步骤

  1. 遍历未排序部分
    • 从数组的第一个元素开始,假设当前位置为最小值。

  2. 寻找最小值
    • 在未排序部分中找到最小值的索引。

  3. 交换元素
    • 将找到的最小值与未排序部分的第一个元素交换位置。

  4. 重复过程
    • 缩小未排序部分的范围,直到整个数组有序。


三、代码实现

1. 升序排序
#include <iostream>
using namespace std;

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

    for (int i = 0; i < n - 1; i++) {
        int minIndex = i; // 假设当前未排序部分的第一个元素是最小值
        // 寻找未排序部分的最小值索引
        for (int j = i + 1; j < n; j++) {
            if (arr[j] < arr[minIndex]) {
                minIndex = j;
            }
        }
        // 交换最小值到已排序部分的末尾
        swap(arr[i], arr[minIndex]);
    }

    // 输出排序后的数组
    for (int i = 0; i < n; i++) {
        cout << arr[i] << " ";
    }
    cout << endl;

    return 0;
}

运行结果

11 12 22 25 64

2. 降序排序
#include <iostream>
using namespace std;

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

    for (int i = 0; i < n - 1; i++) {
        int maxIndex = i; // 假设当前未排序部分的第一个元素是最大值
        // 寻找未排序部分的最大值索引
        for (int j = i + 1; j < n; j++) {
            if (arr[j] > arr[maxIndex]) {
                maxIndex = j;
            }
        }
        // 交换最大值到已排序部分的末尾
        swap(arr[i], arr[maxIndex]);
    }

    // 输出排序后的数组
    for (int i = 0; i < n; i++) {
        cout << arr[i] << " ";
    }
    cout << endl;

    return 0;
}

运行结果

64 25 22 12 11

四、代码解析

  1. 外层循环

    • 控制已排序部分的边界(i 表示当前已排序部分的末尾)。

  2. 内层循环

    • 在未排序部分(从 i+1n-1)中寻找最小值(或最大值)的索引。

  3. 交换操作

    • 将找到的最小值(或最大值)与未排序部分的第一个元素交换。


五、时间复杂度分析

  • 时间复杂度:(O(n^2))(无论最好或最坏情况)。

  • 交换次数:(O(n))(比冒泡排序少,性能略优)。


六、竞赛注意事项

  1. 数据范围
    • 如果 n 超过 10000,选择排序可能超时,建议使用 std::sort

  2. 代码简洁性
    • 选择排序代码简单,适合快速实现小规模排序。

  3. 优化策略
    • 如果已排序部分和未排序部分同时寻找最小值和最大值,可以减少循环次数(进阶技巧)。


七、综合练习

练习 1:排序学生成绩

输入 n 个学生的成绩,按升序输出。

参考代码

#include <iostream>
using namespace std;

int main() {
    int n;
    cin >> n;
    int scores[n];
    for (int i = 0; i < n; i++) {
        cin >> scores[i];
    }

    // 选择排序
    for (int i = 0; i < n - 1; i++) {
        int minIndex = i;
        for (int j = i + 1; j < n; j++) {
            if (scores[j] < scores[minIndex]) {
                minIndex = j;
            }
        }
        swap(scores[i], scores[minIndex]);
    }

    for (int i = 0; i < n; i++) {
        cout << scores[i] << " ";
    }
    cout << endl;

    return 0;
}

练习 2:找出第 k 小的元素

输入一个数组和整数 k,使用选择排序找到第 k 小的元素。

参考代码

#include <iostream>
using namespace std;

int main() {
    int n, k;
    cin >> n >> k;
    int arr[n];
    for (int i = 0; i < n; i++) {
        cin >> arr[i];
    }

    // 选择排序,只排到第 k 个元素
    for (int i = 0; i < k; i++) {
        int minIndex = i;
        for (int j = i + 1; j < n; j++) {
            if (arr[j] < arr[minIndex]) {
                minIndex = j;
            }
        }
        swap(arr[i], arr[minIndex]);
    }

    cout << "第 " << k << " 小的元素:" << arr[k-1] << endl;
    return 0;
}

八、总结

  1. 选择排序的核心是“选择最小值,交换位置”。

  2. 时间复杂度为 (O(n^2)),适合小规模数据。

  3. 竞赛建议:优先使用 std::sort,但选择排序是理解排序原理的基础。

  4. 适用场景:数据量小、代码简洁性要求高时。

相关文章:

  • 蓝桥杯备考:拓扑排序+DFS(信息传递)
  • 数据库同步中间件PanguSync:如何跳过初始数据直接进行增量同步
  • Android生态大变革,谷歌调整开源政策,核心开发不再公开
  • 知识库中嵌入模型(Embedding Models)与重排序模型(Re-ranking Models)推荐工具与库
  • JVM 面经
  • docker run -p 5000:5000 my-flask-app
  • Docker Swarm 和 docker composer 需要 的yaml 文件有什么区别
  • 构建全智能生态,追觅携“技术复利”颠覆“大家电”
  • springboot 四层架构之间的关系整理笔记五
  • DexGrasp Anything:具有物理-觉察的普遍机器人灵巧抓取
  • T-SQL 语言基础:逆透视转换
  • CentOS 安装LAMP全过程 - 完整步骤与最佳实践
  • 【大模型】分词粒度
  • 大模型训练过程中KVCache与MLA
  • k近邻算法K-Nearest Neighbors(KNN)
  • 多个git账户团队写作
  • DATA 动态给值处理
  • linux和windows是采用何种机制保存密码的?
  • 构建高可用性西门子Camstar服务守护者:异常监控与自愈实践
  • 计算机二级WPS Office第四套电子表格
  • 手机搭建网站教程视频教程/项目推广网
  • 武汉营销型网站源码/网销平台排名
  • 网站开发 入门 pdf/打开免费百度啊
  • 网站推广运营/爱站网怎么使用
  • 织梦做的网站有点慢/今日最新国际新闻
  • 哪建设网站好/怎样做推广营销