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

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. 适用场景:数据量小、代码简洁性要求高时。


http://www.kler.cn/a/613166.html

相关文章:

  • OceanBase的闪回查询功能实践
  • 二维数组参数的五种形式
  • 搜广推校招面经五十八
  • 将 char [] str = “hello,you,world” 改为 “world,you,hello“,要求空间复杂度为1
  • 计算机期刊征稿 | 计算机-网络系统:物联网系统架构、物联网使能技术、物联网通信和网络协议、物联网服务和应用以及物联网的社会影响
  • 前端Three.js面试题及参考答案
  • BPM :提升企业流程效率的利器
  • 【今日半导体行业分析】2025年3月24日
  • 【HTML 基础教程】HTML 属性
  • 年化33.9%的稳健策略 | streamlit和dash驱动的智能量化投研(python代码+数据)
  • 刘裕的简介
  • macOS 制作dmg磁盘映像安装包
  • 【PDF提取指定区域内容保存表格】提取PDF电子单据内容,将内容保存为表格并将内容组合进行批量改名操作,基于C++的方式快速实现
  • 头歌 | Linux之用户高级管理
  • 深入解析 TypeScript 核心配置文件 tsconfig.json
  • Spring Boot 3.2性能优化:响应速度提升50%方案
  • 使用multiprocessing
  • 记录一次交易耗时有毛刺TDSQL数据库排查过程
  • ResNet(残差网络)中的残差是什么?
  • 网盘解析工具1.3.0,修改了一些bug,建议更新到此版本