c/c++蓝桥杯经典编程题100道(9)数组排序

devtools/2025/2/12 22:06:01/

数组排序

->返回c/c++蓝桥杯经典编程题100道-目录


目录

数组排序

一、题型解释

二、例题问题描述

三、C语言实现

解法1:冒泡排序(难度★)

解法2:选择排序(难度★)

解法3:快速排序(难度★★★)

四、C++实现

解法1:使用STL的sort函数(难度★☆)

解法2:自定义排序规则(难度★★)

解法3:归并排序(难度★★★)

五、总结对比表


一、题型解释

数组排序是将数组元素按特定顺序(升序、降序或自定义规则)重新排列的操作。常见题型:

  1. 基础排序:将数组按升序或降序排列(如 [3,1,4] → [1,3,4])。

  2. 稳定排序:相同元素的相对顺序不变(如按姓名排序后,同分学生的顺序不变)。

  3. 条件排序:按自定义规则排序(如按绝对值、奇偶性等)。

  4. 部分排序:仅排序数组的一部分(如前k个元素)。


二、例题问题描述

例题1:输入数组 [5, 2, 9, 1, 5],输出升序排列结果 [1, 2, 5, 5, 9]
例题2:输入数组 [-3, 1, -5, 4],按绝对值升序排列输出 [1, -3, 4, -5]
例题3:输入数组 [7, 3, 8, 5],输出降序排列结果 [8, 7, 5, 3]


三、C语言实现

解法1:冒泡排序(难度★)

通俗解释

  • 像水中的气泡,每次将最大的元素“冒”到数组末尾。

c

#include <stdio.h>void bubbleSort(int arr[], int n) {// 外层循环:控制排序轮数(每一轮确定一个最大值的位置)for (int i = 0; i < n-1; i++) { // 内层循环:比较相邻元素并交换for (int j = 0; j < n-1-i; j++) { if (arr[j] > arr[j+1]) { // 交换元素(大的往后“冒”)int temp = arr[j];arr[j] = arr[j+1];arr[j+1] = temp;}}}
}int main() {int arr[] = {5, 2, 9, 1, 5};int n = sizeof(arr) / sizeof(arr[0]);bubbleSort(arr, n);for (int i = 0; i < n; i++) {printf("%d ", arr[i]); // 输出 1 2 5 5 9}return 0;
}

代码逻辑

  1. 外层循环:共进行 n-1 轮(每轮确定一个最大值的位置)。

  2. 内层循环:每轮比较相邻元素,若前大后小则交换。

  3. 优化:第 i 轮时,末尾 i 个元素已有序,无需再比较。

  4. 时间复杂度:O(n²)(最坏情况)。


解法2:选择排序(难度★)

通俗解释

  • 每次从剩余元素中选最小的,放到已排序序列末尾。

c

#include <stdio.h>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; // 更新最小值位置}}// 将最小值与当前位置交换int temp = arr[i];arr[i] = arr[minIndex];arr[minIndex] = temp;}
}int main() {int arr[] = {5, 2, 9, 1, 5};int n = sizeof(arr) / sizeof(arr[0]);selectionSort(arr, n);for (int i = 0; i < n; i++) {printf("%d ", arr[i]); // 输出 1 2 5 5 9}return 0;
}

代码逻辑

  1. 外层循环:遍历数组,每轮确定一个最小值的位置。

  2. 内层循环:在未排序部分中找到最小值的位置 minIndex

  3. 交换操作:将最小值与当前未排序部分的第一个元素交换。

  4. 时间复杂度:O(n²)。


解法3:快速排序(难度★★★)

通俗解释

  • 像“分而治之”,选一个基准值,小的放左边,大的放右边,递归处理左右子数组。

c

#include <stdio.h>// 分区函数:将数组分为左右两部分,返回基准值的位置
int partition(int arr[], int low, int high) {int pivot = arr[high]; // 选最后一个元素作为基准值int i = low - 1;       // 指向比基准值小的区域的末尾for (int j = low; j < high; j++) {if (arr[j] < pivot) {i++;// 交换元素,将小的值移到左边int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}}// 将基准值放到正确位置int temp = arr[i+1];arr[i+1] = arr[high];arr[high] = temp;return i + 1;
}// 递归排序函数
void quickSort(int arr[], int low, int high) {if (low < high) {int pi = partition(arr, low, high); // 获取基准值位置quickSort(arr, low, pi - 1);        // 排序左半部分quickSort(arr, pi + 1, high);       // 排序右半部分}
}int main() {int arr[] = {5, 2, 9, 1, 5};int n = sizeof(arr) / sizeof(arr[0]);quickSort(arr, 0, n-1);for (int i = 0; i < n; i++) {printf("%d ", arr[i]); // 输出 1 2 5 5 9}return 0;
}

代码逻辑

  1. 分区函数

    • 选择基准值 pivot(通常选最后一个元素)。

    • 遍历数组,将小于 pivot 的元素移到左侧。

    • 最后将 pivot 放到中间位置。

  2. 递归排序

    • 对基准值左侧和右侧的子数组递归调用快速排序。

  3. 时间复杂度:平均 O(n log n),最坏 O(n²)。


四、C++实现

解法1:使用STL的sort函数(难度★☆)

通俗解释

  • 直接调用C++标准库的排序函数,一行代码完成排序。

cpp

#include <iostream>
#include <algorithm> // 包含sort函数
#include <vector>
using namespace std;int main() {vector<int> vec = {5, 2, 9, 1, 5};sort(vec.begin(), vec.end()); // 默认升序排序for (int num : vec) {cout << num << " "; // 输出 1 2 5 5 9}return 0;
}

代码逻辑

  1. sort函数

    • 参数1:起始迭代器(vec.begin())。

    • 参数2:结束迭代器(vec.end())。

    • 默认按升序排序,底层实现为快速排序的优化版本(IntroSort)。

  2. 时间复杂度:O(n log n)。


解法2:自定义排序规则(难度★★)

通俗解释

  • 按绝对值排序或降序排序,需自定义比较函数。

cpp

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;// 自定义比较函数:按绝对值升序
bool compareAbs(int a, int b) {return abs(a) < abs(b);
}int main() {vector<int> vec = {-3, 1, -5, 4};sort(vec.begin(), vec.end(), compareAbs); // 传入自定义比较函数for (int num : vec) {cout << num << " "; // 输出 1 -3 4 -5}return 0;
}

代码逻辑

  1. 比较函数

    • 若 compare(a, b) 返回 true,则 a 排在 b 前面。

    • 此处按绝对值升序排列。

  2. 函数传递:将函数名 compareAbs 作为参数传递给 sort


解法3:归并排序(难度★★★)

通俗解释

  • 将数组分成两半,分别排序后合并。

cpp

#include <iostream>
#include <vector>
using namespace std;// 合并两个有序数组
void merge(vector<int>& arr, int left, int mid, int right) {vector<int> temp(right - left + 1);int i = left, j = mid + 1, k = 0;// 比较两个子数组的元素,依次放入临时数组while (i <= mid && j <= right) {if (arr[i] <= arr[j]) {temp[k++] = arr[i++];} else {temp[k++] = arr[j++];}}// 将剩余元素复制到临时数组while (i <= mid) temp[k++] = arr[i++];while (j <= right) temp[k++] = arr[j++];// 将临时数组拷贝回原数组for (int p = 0; p < k; p++) {arr[left + p] = temp[p];}
}// 递归排序函数
void mergeSort(vector<int>& arr, int left, int right) {if (left >= right) return;int mid = left + (right - left) / 2;mergeSort(arr, left, mid);      // 排序左半部分mergeSort(arr, mid + 1, right); // 排序右半部分merge(arr, left, mid, right);   // 合并两部分
}int main() {vector<int> vec = {5, 2, 9, 1, 5};mergeSort(vec, 0, vec.size() - 1);for (int num : vec) {cout << num << " "; // 输出 1 2 5 5 9}return 0;
}

代码逻辑

  1. 分治思想

    • 递归将数组分成两半,直到每个子数组只有一个元素。

    • 合并两个有序子数组。

  2. 合并操作

    • 创建临时数组存储合并结果。

    • 比较两个子数组的元素,按序放入临时数组。

  3. 时间复杂度:O(n log n)。


五、总结对比表

方法时间复杂度空间复杂度优点缺点
冒泡排序O(n²)O(1)简单直观效率低,仅适合小数据
选择排序O(n²)O(1)简单,交换次数少效率低
快速排序O(n log n) 平均O(log n)高效,适合大数据最坏情况O(n²)
STL sortO(n log n)O(log n)极简代码,高效依赖STL库
归并排序O(n log n)O(n)稳定排序,适合链表需要额外空间

->返回c/c++蓝桥杯经典编程题100道-目录


http://www.ppmy.cn/devtools/158317.html

相关文章

基于生成式语言模型的就业指导

一、引言 在当今竞争激烈的就业市场中&#xff0c;求职者面临着诸多挑战&#xff0c;如职业规划迷茫、简历撰写困难、面试准备不足等。生成式语言模型&#xff0c;如ChatGPT等&#xff0c;凭借其强大的语言理解和生成能力&#xff0c;为求职者提供了全新的就业指导途径。本指导…

dbeaver 安装之后出现mysql连接异常问题

1.手动下载mysql驱动程序 参考文档DBeaver连接mysql驱动下载失败怎么办&#xff1f;-CSDN博客 2.添加对应的下载程序到dbeaver 【DBeaver】缺少mysql驱动_dbeaver连接mysql缺少驱动-CSDN博客 配置mysql 地址端口账户等即可使用

DeepSeek关联PPT使用教程

在当今数字化办公和学习的快节奏环境中&#xff0c;制作高质量的PPT已经成为我们工作和学习中不可或缺的技能。无论是商务汇报、学术展示还是教学课件&#xff0c;一份出色的PPT都能让你的表达更加清晰、有力&#xff0c;吸引观众的注意力。然而&#xff0c;制作PPT往往需要投入…

网络基础知识与配置

目录 网络基础知识 &#xff08;一&#xff09;网络的概念 &#xff08;二&#xff09;网络协议 &#xff08;三&#xff09;网络拓扑结构 &#xff08;四&#xff09;IP地址和子网掩码 显示和配置网络接口 &#xff08;一&#xff09;在Windows系统中 &#xff08;二&a…

[LeetCode]day20 383.赎金信

题目链接 题目描述 给你两个字符串&#xff1a;ransomNote 和 magazine &#xff0c;判断 ransomNote 能不能由 magazine 里面的字符构成。 如果可以&#xff0c;返回 true &#xff1b;否则返回 false 。 magazine 中的每个字符只能在 ransomNote 中使用一次。 示例 1&am…

LeetCode1240 铺瓷砖

一、问题描述 给定一个大小为 n x m 的长方形&#xff0c;我们需要找出贴满这个矩形所需的整数边正方形的最小数量。例如&#xff0c;当 n 2&#xff0c;m 3 时&#xff0c;需要 3 个正方形来覆盖这个长方形&#xff0c;其中包括 2 个 1x1 的正方形和 1 个 2x2 的正方形。 …

怎样确定网站访问速度出现问题是后台还是服务器造成的?

网站的访问速度会影响到用户的体验感&#xff0c;当网络过于卡顿或访问速度较慢时&#xff0c;会给用户带来不好的体验感&#xff0c;但是网站访问速度不仅会是后台造成影响的&#xff0c;也可能是服务器的原因&#xff0c;那么我们该如何分辨呢&#xff1f; 当网站使用了数据库…

oa二开问题

向第三方发送请求速度会极慢 测试数据&#xff1a; 注释掉 发送请求的那一行&#xff1a; 2s-3s 没注释掉&#xff1a; 20s 解决方案&#xff1a;(暂无) 可能原因是办公电脑&#xff0c;硬件不行&#xff0c;用postman 测试过 api的响应时间很快的 用了hutool 和 oa客服封装…