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

C/C++每日一练:实现选择排序

选择排序

        选择排序是一种简单直观的排序算法,时间复杂度为O(n^{2}),其中 n 是数组长度,不适合大数据集的排序,适合于元素较少且对性能要求不高的场景。

        选择排序的基本思想是:每次从未排序部分选择最小的元素,将其放到已排序部分的末尾。这样经过多轮操作后,整个数组会被逐步排好序。

        具体步骤如下:

  1. 初始化:将第一个元素作为已排序区,剩余部分作为未排序区。
  2. 遍历未排序区:从未排序区间找出最小的元素,记下其位置。
  3. 交换位置:将找到的最小元素与当前未排序区的第一个元素交换。
  4. 重复上述步骤:每次将已排序区的范围扩大一个元素,直到整个数组排序完成。

题目要求

        实现一个选择排序算法,用于对整数数组进行升序排序。输入是一个包含若干整数的数组,输出是排序后的数组。要求在原数组上进行排序,不借助额外的数组空间(即就地排序)。

做题思路

  1. 初始化已排序区间和未排序区间:数组已排序区间最开始为空,所有元素都在未排序区间中。
  2. 逐步扩展已排序区间:遍历数组,从未排序区间中找出最小值的下标,将其与当前未排序区间的起始元素交换。
  3. 更新边界:每次将已排序区间的范围扩大一个元素。

过程解析

        假设有一个数组 arr,长度为 n。使用变量 minIndex 记录当前未排序区间中最小值的下标。具体步骤如下:

  1. 外层循环控制已排序区间的结束位置 i(从 0 开始)。
  2. 每次将未排序区间的第一个元素设为最小值(minIndex = i)。
  3. 内层循环从 i + 1 到 n - 1,找到未排序区间的最小值的下标并更新到 minIndex。
  4. 找到最小值后,与当前未排序区间的第一个元素交换位置(如果 i 和 minIndex 不相同)。

运用到的知识点

  • 数组:数组的定义和遍历
  • 双层循环:外层循环控制排序轮数,内层循环查找未排序区间的最小值
  • 条件判断和交换操作:根据下标交换两个元素的值

示例代码

C 实现

#include <stdio.h> // 引入标准输入输出库,用于printf等函数  

// 定义选择排序函数,接收一个整型数组和数组的长度作为参数  
void selectionSort(int arr[], int n) {
    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;                 // 更新最小值下标为当前更小元素的下标  
            }
        }
        if (minIndex != i) {                  // 如果找到的最小值不是当前元素(即最小值下标发生了改变)  
            int temp = arr[i];                // 交换元素,将找到的最小值元素与当前元素位置互换  
            arr[i] = arr[minIndex];
            arr[minIndex] = temp;
        }
    }
}

// 定义打印数组函数,接收一个整型数组和数组的长度作为参数  
void printArray(int arr[], int n) {
    for (int i = 0; i < n; i++) {             // 遍历数组  
        printf("%d ", arr[i]);                // 打印每个元素,元素之间用空格分隔  
    }
    printf("\n");                             // 打印完所有元素后换行  
}

int main() 
{
    int arr[] = { 64, 25, 12, 22, 11 };         // 定义一个整型数组并初始化  
    int n = sizeof(arr) / sizeof(arr[0]);     // 计算数组的长度,即数组中元素的个数  
    selectionSort(arr, n);                    // 调用选择排序函数对数组进行排序  
    printf("排序后的数组: ");                 // 打印提示信息  
    printArray(arr, n);                       // 调用打印数组函数输出排序后的数组  
    return 0;                                 // 程序正常结束,返回0  
}

C++ 实现

#include <iostream> // 引入输入输出流库,用于输入输出操作  
#include <vector>   // 引入向量库,用于使用动态数组  
  
using namespace std; // 使用标准命名空间,避免每次调用标准库时都需要加std::前缀  
  
// 定义选择排序函数,接收一个整数向量的引用作为参数,避免复制整个数组  
void selectionSort(vector<int>& arr) {  
    int n = arr.size(); // 获取数组的长度  
    for (int i = 0; i < n - 1; i++) {             // 外层循环:从第0个元素遍历到倒数第二个元素  
        int minIndex = i;                         // 假设当前未排序区的第一个元素为最小值,并记录其下标  
        for (int j = i + 1; j < n; j++) {         // 内层循环:从当前元素的下一个元素开始,遍历未排序区  
            if (arr[j] < arr[minIndex]) {         // 如果找到比当前最小值还小的元素  
                minIndex = j;                     // 更新最小值下标为当前更小元素的下标  
            }  
        }  
        if (minIndex != i) {                      // 如果找到的最小值下标不是当前元素的下标(即最小值发生了移动)  
            swap(arr[i], arr[minIndex]);          // 使用C++内置的swap函数交换两个元素的位置,将最小值放到已排序区的末尾  
        }  
    }  
}  
  
// 定义打印数组函数,接收一个整数向量的常量引用作为参数,避免修改原数组  
void printArray(const vector<int>& arr) {  
    for (int i : arr) { // 使用范围for循环遍历数组中的每个元素  
        cout << i << " "; // 打印每个元素,元素之间用空格分隔  
    }  
    cout << endl; // 打印完所有元素后换行  
}  
  
int main() 
{  
    vector<int> arr = {64, 25, 12, 22, 11}; // 定义一个整数向量并初始化  
    selectionSort(arr);                           // 调用选择排序函数对数组进行排序  
    cout << "排序后的数组: "; // 打印提示信息  
    printArray(arr);                              // 调用打印数组函数输出排序后的数组  
    return 0; // 程序正常结束,返回0  
}


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

相关文章:

  • golang , chan学习
  • 面向未来的教育技术:智能成绩管理系统的开发
  • ROS1入门教程6:复杂行为处理
  • 密码学期末考试笔记
  • OpenCV相机标定与3D重建(26)计算两个二维点集之间的部分仿射变换矩阵(2x3)函数 estimateAffinePartial2D()的使用
  • Java设计模式 —— 【结构型模式】外观模式详解
  • 大语言模型及LangChain介绍
  • 【oracle】正则表达式
  • 蓝禾,汤臣倍健,三七互娱,得物,顺丰,快手,途游游戏,埃科光电25秋招内推
  • Bolt.new: 终极自动化全栈编程工具,吊打 cursor
  • 【ZZULI】数据库第二次实验
  • C# 结构型设计模式----外观模式
  • 图像的特征类别
  • 2024前端面试训练计划-高频题-JavaScript基础篇
  • ubuntu禁止自动更新设置
  • 新浪新闻探索大会|赵世奇:文心智能体解锁AI浪潮中的商业新范式
  • 《别傻等外卖了!Java 中的 CompletableFuture 比 Future 香十倍!》
  • computed拦截v-model
  • 「Mac畅玩鸿蒙与硬件10」鸿蒙开发环境配置篇10 - 项目实战:计数器应用
  • k8s集群 ceph rbd 存储动态扩容
  • Java项目实战II基于Java+Spring Boot+MySQL的植物健康系统(开发文档+数据库+源码)
  • 网络搜索引擎Shodan(5)
  • Lucene数据写入流程
  • 【qt qtcreator使用】【正点原子】嵌入式Qt5 C++开发视频
  • Python爬虫:在1688上“侦探游戏”获取店铺详情
  • 如何利用斗篷cloak技术做F牌独立站?