C++-排序算法详解
目录
一. 冒泡排序:
二. 插入排序:
三. 快速排序:
四. 选择排序
五, 归并排序
六, 堆排序.
排序算法是一种将一组数据按照特定顺序(如升序或降序)进行排列的算法。
其主要目的是对一组无序的数据进行整理,使得它们呈现出一定的有序性。这样做有很多好处,比如:
- 方便查找和检索数据,提高搜索效率。
- 使数据更易于理解和分析。
- 在某些情况下,可以优化其他算法的性能。
主要排序算法有:冒泡排序.插入排序,快速排序.选择排序,归并排序,堆排序.
| 排序 | 优点 | 缺点 |
| 冒泡排序 | 简单易懂,容易实现 | 效率相对较低 |
| 插入排序 | 对于接近有序的数据效率较高 | 处理大规模无序数据时性能可能不太理想。 |
| 快速排序 | 平均性能较好,在大多数情况下效率较高 | 最坏情况下(比如已经有序或逆序)的性能会退化。 |
| 选择排序 | 算法简单直观,易于理解和实现。 | 它的比较次数较多,性能相对不是特别高 |
| 归并排序 | 具有稳定的性能,时间复杂度在最坏、平均和最好情况下都是O(nlogn) | 需要额外的空间来进行合并操作 |
| 堆排序 | 在最坏情况下性能也较好 | 不太稳定。 |
一. 冒泡排序:
冒泡排序的优点是简单易懂,容易实现。缺点是效率相对较低,尤其是对于基本有序的数组,仍然需要进行大量的比较和交换操作。
冒泡排序是一种简单直观的排序算法。
基本原理:
- 它通过反复比较相邻的元素,如果顺序不对则进行交换,并将最大的元素逐步“冒泡”到数组的末尾。
- 经过一轮比较交换后,最大的元素就会处于正确位置,然后对剩余未排序部分重复这个过程,直到整个数组都被排序。
以下是对冒泡排序过程的详细解释:
假设要排序的数组为 arr[n]:
- 从数组的第一个元素开始,比较相邻的元素。如果前一个元素大于后一个元素,就交换它们的位置。
- 对整个数组进行这样的比较和交换操作,完成后,最大的元素就会“浮”到数组的末尾。
- 忽略已经排序好的最后一个元素,对剩下的元素重复步骤 1 和 2。
- 不断重复这个过程,直到整个数组都被排序。
以下是冒泡排序的 C++ 代码示例:
#include <iostream>void bubbleSort(int arr[], int n) {for (int i = 0; i < n - 1; i++) {for (int j = 0; j < n - i - 1; j++) {if (arr[j] > arr[j + 1]) {int temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;}}}
}int main() {int arr[] = {64, 34, 25, 12, 22, 11, 90};int n = sizeof(arr) / sizeof(arr[0]);bubbleSort(arr, n);for (int i = 0; i < n; i++) {std::cout << arr[i] << " ";}return 0;
} 
二. 插入排序:
插入排序的优点是对于接近有序的数据效率较高,所需的比较和交换操作相对较少。缺点是在处理大规模无序数据时性能可能不太理想。
基本原理:
它逐个将元素插入到已排序的部分中,以达到整个序列有序的目的。
具体步骤如下:
- 从第二个元素开始,将当前元素与已排序部分从后往前依次比较。
- 如果当前元素小于比较的元素,就将比较的元素向后移动一位。
- 一直重复这个过程,直到找到合适的位置插入当前元素。
- 然后继续处理下一个未排序的元素,重复上述操作,直到所有元素都被插入到合适位置。
下面是插入排序的 C++ 代码示例:
#include <iostream>void insertionSort(int arr[], int n) {for (int i = 1; i < n; i++) {int key = arr[i];int j = i - 1;while (j >= 0 && arr[j] > key) {arr[j + 1] = arr[j];j = j - 1;}arr[j + 1] = key;}
}int main() {int arr[] = { 12, 11, 13, 5, 6 };int n = sizeof(arr) / sizeof(arr[0]);insertionSort(arr, n);for (int i = 0; i < n; i++) {std::cout << arr[i] << " ";}return 0;
} 
三. 快速排序:
快速排序的优点是平均性能较好,在大多数情况下效率较高。但它在最坏情况下(比如已经有序或逆序)的性能会退化。
基本原理:
- 选择一个基准元素。
- 将数组分为两个子数组,一个子数组中的元素都小于等于基准元素,另一个子数组中的元素都大于基准元素。
- 对这两个子数组分别进行快速排序。
具体步骤:
- 选择数组中的一个元素作为基准(通常选择第一个或最后一个元素)。
- 通过一趟排序将数组分为两部分,使得基准左边的元素都小于基准,右边的元素都大于基准。
- 对基准左边和右边的子数组分别递归地进行快速排序,直到整个数组有序。
以下是一个快速排序的 C++ 代码示例:
#include <iostream>// 交换两个元素
void swap(int* a, int* b) {int temp = *a;*a = *b;*b = temp;
}// 划分函数
int partition(int arr[], int low, int high) {int pivot = arr[high];int i = (low - 1);for (int j = low; j <= high - 1; j++) {if (arr[j] <= pivot) {i++;swap(&arr[i], &arr[j]);}}swap(&arr[i + 1], &arr[high]);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[] = { 12, 11, 13, 5, 6 };int n = sizeof(arr) / sizeof(arr[0]);quickSort(arr, 0, n - 1);for (int i = 0; i < n; i++) {std::cout << arr[i] << " ";}return 0;
} 
四. 选择排序
选择排序的优点是算法简单直观,易于理解和实现。缺点是它的比较次数较多,性能相对不是特别高,尤其是对于较大规模的数据。例如,对于一个包含n个元素的数组,它需要进行大约n^2/2次比较。
基本原理:
在未排序的序列中不断地选择最小(或最大)元素,并将其放到已排序序列的末尾。
具体步骤:
- 从整个数组的第一个元素开始,遍历所有未排序的元素,找出其中最小(或最大)的元素。
- 将找到的最小(或最大)元素与数组的第一个未排序元素交换位置。
- 此时第一个元素就已排序,然后从第二个未排序元素开始重复上述过程,直到整个数组都被排序。
以下是选择排序的 C++代码示例:
#include <iostream>void selectionSort(int arr[], int n) {for (int i = 0; i < n - 1; i++) {int min_idx = i;for (int j = i + 1; j < n; j++) {if (arr[j] < arr[min_idx]) {min_idx = j;}}if (min_idx != i) {int temp = arr[i];arr[i] = arr[min_idx];arr[min_idx] = temp;}}
}int main() {int arr[] = { 12, 11, 13, 5, 6 };int n = sizeof(arr) / sizeof(arr[0]);selectionSort(arr, n);for (int i = 0; i < n; i++) {std::cout << arr[i] << " ";}return 0;
}
五, 归并排序
归并排序的优点是具有稳定的性能,时间复杂度在最坏、平均和最好情况下都是O(nlogn)。缺点是需要额外的空间来进行合并操作。
基本原理:
将数组不断地分成两半,对每一半进行排序,然后再将排序好的两半合并起来。
具体步骤如下:
- 把数组分成两半。
- 对左右两部分分别递归地进行归并排序。
- 将已经排序好的左右两部分合并为一个有序的数组。
在合并过程中,通过比较左右两部分的元素,依次将较小的元素放入新的合并后的数组中。
以下是归并排序的 C++ 代码示例:
#include <iostream>
#include <vector>// 合并函数
void merge(std::vector<int>& arr, int l, int m, int r) {int n1 = m - l + 1;int n2 = r - m;std::vector<int> left(n1), right(n2);for (int i = 0; i < n1; i++)left[i] = arr[l + i];for (int j = 0; j < n2; j++)right[j] = arr[m + 1 + j];int i = 0, j = 0, k = l;while (i < n1 && j < n2) {if (left[i] < right[j])arr[k++] = left[i++];elsearr[k++] = right[j++];}while (i < n1)arr[k++] = left[i++];while (j < n2)arr[k++] = right[j++];
}// 归并排序函数
void mergeSort(std::vector<int>& arr, int l, int r) {if (l < r) {int m = l + (r - l) / 2;mergeSort(arr, l, m);mergeSort(arr, m + 1, r);}
}int main() {std::vector<int> arr = { 12, 11, 13, 5, 6, 7, 8, 9, 10 };mergeSort(arr, 0, arr.size() - 1);for (int i = 0; i < arr.size(); i++) {std::cout << arr[i] << " ";}std::cout << std::endl;return 0;
}
六, 堆排序.
堆排序是一种选择排序。
堆排序的时间复杂度为O(n log n) ,空间复杂度为O(1) 。它的优点是在最坏情况下性能也较好,缺点是不太稳定。
基本概念:
堆是一种特殊的数据结构,可以分为大顶堆和小顶堆。大顶堆中每个节点的值都不小于其孩子节点的值,小顶堆则相反。
原理:
- 先将数组构建成一个大顶堆。
- 不断地将堆顶元素(最大值)与未排序部分的最后一个元素交换,然后调整堆,使其重新成为大顶堆。
具体步骤:
- 构建大顶堆:从最后一个非叶子节点开始,依次进行调整,使每个节点及其子树都满足大顶堆的性质。
- 排序过程:
- 将堆顶元素和未排序部分的最后一个元素交换。
- 对堆顶进行调整,使其重新成为大顶堆。
以下是堆排序的 C++ 代码示例:
#include <iostream>// 调整堆
void heapify(int arr[], int n, int i) {int largest = i;int l = 2 * i + 1;int r = 2 * i + 2;if (l < n && arr[l] > arr[largest])largest = l;if (r < n && arr[r] > arr[largest])largest = r;if (largest!= i) {std::swap(arr[i], arr[largest]);heapify(arr, n, largest);}
}// 堆排序函数
void heapSort(int arr[], int n) {for (int i = n / 2 - 1; i >= 0; i--)heapify(arr, n, i);for (int i = n - 1; i > 0; i--) {std::swap(arr[0], arr[i]);heapify(arr, i, 0);}
}int main() {int arr[] = {12, 11, 13, 5, 6};int n = sizeof(arr) / sizeof(arr[0]);heapSort(arr, n);for (int i = 0; i < n; i++) {std::cout << arr[i] << " ";}return 0;
}

相关文章:
C++-排序算法详解
目录 一. 冒泡排序: 二. 插入排序: 三. 快速排序: 四. 选择排序 五, 归并排序 六, 堆排序. 排序算法是一种将一组数据按照特定顺序(如升序或降序)进行排列的算法。 其主要目的是对一组无序的数据进行整理&#…...
Kotlin 引用(双冒号::)
文章目录 双冒号::引用函数普通函数成员函数类构造函数 引用变量(很少用)普通变量成员变量 双冒号:: Kotlin 中可以使用双冒号::对某一变量、函数进行引用。 Note:MyClass::class可用于获取KClass<MyClass>,此时的双冒号::…...
C++ day3练习
设计一个Per类,类中包含私有成员:姓名、年龄、指针成员身高、体重,再设计一个Stu类,类中包含私有成员:成绩、Per类对象p1,设计这两个类的构造函数、析构函数。 #include <iostream>using namespace std;class Per{private:…...
命令模式(行为型)
目录 一、前言 二、命令模式 三、总结 一、前言 命令模式(Command Pattern)是一种行为型设计模式,命令模式将一个请求封装为一个对象,从而可以用不同的请求对客户进行参数化;对请求排队或记录请求日志,以…...
韩雪医生针药结合效果好 患者赠送锦旗表感谢
任先生长年献血身体出现不适,身上多处发黑发冷,伴随疼痛,而且还有慢性腹泻的症状。他曾前往苏州各大医馆做过检查,均查不出异常,但身体确实不舒服,面色晦暗。 后来他来到李良济,求诊于韩雪医生。…...
【队列、堆、栈 解释与区分】
文章目录 概要队列(Queue)定义特性应用场景 堆(Heap)定义特性应用场景 栈(Stack)定义特性应用场景 总结 概要 队列、堆和栈是三种常见的数据结构,它们各自具有不同的特性和应用场景。下面是对这…...
NTP网络时间服务器_安徽京准电钟
NTP网络时间服务器_安徽京准电钟 NTP网络时间服务器_安徽京准电钟 概述 NTP网络时间服务器是一款支持NTP和SNTP网络时间同步协议,高精度、大容量、高品质的高科技时钟产品。 NTP网络时间服务器设备采用冗余架构设计,高精度时钟直接来源于北斗、GPS系统中…...
Java:爬虫框架
一、Apache Nutch2 【参考地址】 Nutch 是一个开源Java 实现的搜索引擎。它提供了我们运行自己的搜索引擎所需的全部工具。包括全文搜索和Web爬虫。 Nutch 致力于让每个人能很容易, 同时花费很少就可以配置世界一流的Web搜索引擎. 为了完成这一宏伟的目标, Nutch必须能够做到…...
ChatGPT基本原理详细解说
ChatGPT基本原理详细解说 引言 在人工智能领域,自然语言处理(NLP)一直是研究的热点之一。随着技术的发展,我们见证了从简单的聊天机器人到复杂的语言模型的演变。其中,ChatGPT作为一项突破性技术,以其强大…...
Java日期时间处理深度解析:从Date、Calendar到SimpleDateFormat
粉丝福利:微信搜索「万猫学社」,关注后回复「电子书」,免费获取12本Java必读技术书籍。 Java中的日期和时间处理 在Java中,日期和时间的处理一直是一个复杂而繁琐的任务。那么,为什么会这样呢?让我们先来看…...
Flutter 中的 CupertinoUserInterfaceLevel 小部件:全面指南
Flutter 中的 CupertinoUserInterfaceLevel 小部件:全面指南 Flutter 是一个功能强大的 UI 框架,由 Google 开发,允许开发者使用 Dart 语言构建跨平台的移动、Web 和桌面应用。在 Flutter 的 Cupertino(iOS 风格)组件…...
区块链学习记录01
在学习过程中所遇到的问题,及其解。 Q:区块链中分布式账本的存在,让所有人都知道资金的变动吗? A:区块链中的分布式账本确实让参与网络的所有节点都能够了解账户之间的资金变动。这是因为区块链是一个分布式数据库,其中包含着所…...
python--装饰器
[掌握]装饰器入门 语法糖 目标:掌握装饰器的快速使用。 装饰器本质上就是闭包,但装饰器有特殊作用,那就是:在不改变原有函数的基础上,给原有函数增加额外功能。 定义装饰器: def outer([外面参数列表]):…...
Docker:定义未来的软件部署
1. 概述 Docker,这个在技术圈里频频被提及的名词,实际上是一种开源的容器化技术。它允许开发者将应用程序及其依赖打包成一个标准化的单元——容器,确保应用在任何环境中都能够一致地运行。从开发者的本地机器到全球的云平台,Doc…...
ros常用环境变量
RMW层DDS实现 rti dds export RMW_IMPLEMENTATIONrmw_connextdds //rti dds 或者 RMW_IMPLEMENTATIONrmw_connextdds ros2 run ... export NDDS_QOS_PROFILES/qos.xml //配置qos文件fastdds export RMW_IMPLEMENTATIONrmw_fastrtps_cpp 或者 RMW_IMPLEMENTATIONrmw_fas…...
python学习 - 爬虫案例 - 爬取链接房产信息入数据库代码实例
#codingutf-8 #!/usr/bin/python # 导入requests库 import requests # 导入文件操作库 import os import re import bs4 from bs4 import BeautifulSoup import sys from util.mysql_DBUtils import mysql# 写入数据库 def write_db(param):try:sql "insert into house (…...
Git 完整操作之记录
目录 一 . Git 基本操作流程及示例代码 1. 初始化 Git 仓库 2. 克隆远程仓库 3. 检查当前状态 4. 添加文件到暂存区 5. 提交更改 6. 查看提交历史 7. 创建分支 8. 切换分支 9. 合并分支 10. 推送更改到远程仓库 11. 拉取远程仓库的更改 12. 回滚到上一个版本 二…...
mediaPlayer的内存泄露解决方法
MediaPlayer在Android中用于播放音频和视频。如果不正确管理,MediaPlayer可能会导致内存泄漏,尤其是当它被用于多个Activity或长时间播放时。以下是一些解决MediaPlayer内存泄漏的方法: ### 1. 及时释放资源 当MediaPlayer不再使用时&#x…...
delphi3层 delphi 3层
一、为DataSnap系统服务程序添加描述 procedure TServerContainer.ServiceAfterInstall(Sender: TService); var reg: TRegistry; begin reg : TRegistry.Create; try with reg do begin RootKey : HKEY_LOCAL_MACHINE; if OpenKey(SYSTEM/CurrentC…...
Python编程学习第一篇——制作一个小游戏休闲一下
到上期结束,我们已经学习了Python语言的基本数据结构,除了数值型没有介绍,数值型用的非常广,但也是最容易理解的,将在未来的学习中带大家直接接触和学习掌握。后续我们会开始学习这门语言的一些基础语法和编程技巧&…...
SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...
【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...
FastAPI 教程:从入门到实践
FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,支持 Python 3.6。它基于标准 Python 类型提示,易于学习且功能强大。以下是一个完整的 FastAPI 入门教程,涵盖从环境搭建到创建并运行一个简单的…...
[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...
大学生职业发展与就业创业指导教学评价
这里是引用 作为软工2203/2204班的学生,我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要,而您认真负责的教学态度,让课程的每一部分都充满了实用价值。 尤其让我…...
HarmonyOS运动开发:如何用mpchart绘制运动配速图表
##鸿蒙核心技术##运动开发##Sensor Service Kit(传感器服务)# 前言 在运动类应用中,运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据,如配速、距离、卡路里消耗等,用户可以更清晰…...
【JVM】Java虚拟机(二)——垃圾回收
目录 一、如何判断对象可以回收 (一)引用计数法 (二)可达性分析算法 二、垃圾回收算法 (一)标记清除 (二)标记整理 (三)复制 (四ÿ…...
C++ 设计模式 《小明的奶茶加料风波》
👨🎓 模式名称:装饰器模式(Decorator Pattern) 👦 小明最近上线了校园奶茶配送功能,业务火爆,大家都在加料: 有的同学要加波霸 🟤,有的要加椰果…...
探索Selenium:自动化测试的神奇钥匙
目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...


