c++排序算法

冒泡排序

//冒泡 通过多次交换相邻元素将较大(或较小)的元素逐渐 "浮" 到数组的一端。该算法的时间复杂度为 O(N^2)。
void bubbleSort(vector<int>&arr) {int n=arr.size();for(int i=0; i<n-1; i++) {for(int j=0; j<n-i-1; j++) {if(arr[j]>arr[j+1]) {swap(arr[j],arr[j+1]);}}}
}

两层循环,一次次比较交换。

选择排序

//选择排序 在每次迭代中选择未排序部分的最小(或最大)元素,并将其放在已排序部分的末尾。时间复杂度为 O(N^2)。void selectionSort(std::vector<int>& arr) {int n = arr.size();for(int i=0; i<n; i++) {int minIndex=i;for(int j=i+1; j<n; j++) { //找未排序部分的最小值对应的indexif(arr[j]<arr[minIndex]) {minIndex=j;}}//找到未排序部分的最小值之后,需要放在有序部分的末尾,也就是i位置.所以交换.swap(arr[i],arr[minIndex]);}
}

在未排序部分选一个最小的放到有序部分末尾。

插入排序

//插入排序  将未排序部分的元素逐个插入到已排序部分的正确位置。时间复杂度为 O(N^2),但对于小型数据集或部分已排序的数据,插入排序具有较好的性能。
void insertionSort(std::vector<int>& arr) {int n = arr.size();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;}arr[j+1]=key;}
}

从未排序部分取一个插入到有序部分。

快速排序

//快速排序(Quick Sort):也是采用分治策略的排序算法,通过选择一个基准值,将数据分为小于基准值和大于基准值的两部分,然后递归地对这两部分进行排序。时间复杂度为 O(NlogN),具有较好的性能。
// 将数组以升序进行排列!
// 分区操作函数,将数组分成两个部分并返回基准元素的最终位置
void quickSort(vector<int> &nums, int l, int r) {if (l + 1 >= r) {return;}int first = l, last = r - 1, key = nums[first];while (first < last) {while(first < last && nums[last] > key) {--last;}//从右往左找小于基枢的值nums[first] = nums[last];//把小于基枢的值赋给左边.while (first < last && nums[first] < key) {++first;}//从左往右找大于基枢的值nums[last] = nums[first]; //找到之后把这个大于基枢的值再赋给右边.}//这样循环下去,first指向的位置最终左边都是小于基枢,右边都是大于基枢. first=last把基枢位置确定下来.nums[first] = key;quickSort(nums, l, first);quickSort(nums, first + 1, r);
}

分支法,先分区,找到分区的位置后,两边继续

quickSort(nums, l, first);
quickSort(nums, first + 1, r);

首先设置第一个为基枢。从右往左找比基枢小的值,然后复制到first,接着从first向右找第一个比基枢大的值,复制到fast位置,然后fast往左找小的,再给first赋值,直到first和last相等,此次,基枢位置确定,把最开始设置的基枢赋值过来。基枢位置确定之后,就有了左右分区。在左右分区继续快排。

归并排序

//归并排序
void merge_sort(vector<int> &nums, int l, int r, vector<int> &temp) {if (l + 1 >= r) {return;}
// divideint m = l + (r - l) / 2;merge_sort(nums, l, m, temp);merge_sort(nums, m, r, temp);
// conquerint p = l, q = m, i = l;while (p < m || q < r) {if (q >= r || (p < m && nums[p] <= nums[q])) {temp[i++] = nums[p++];} else {temp[i++] = nums[q++];}}for (i = l; i < r; ++i) {nums[i] = temp[i];}
}

在合并过程中,我们使用双指针 pq 分别指向左右两个子数组的起始位置,然后比较指针位置处的元素大小,将较小的元素放入临时数组 temp 中。最后,将临时数组中的元素复制回原数组。

int main() {std::vector<int> numbers = {5, 2, 8, 1, 3};//	std::sort(numbers.begin(), numbers.end());//快排 std::sort:使用快速排序(Quick Sort)实现的排序算法,平均时间复杂度为 O(NlogN)
//	std::stable_sort(numbers.begin(), numbers.end());//std::stable_sort:使用归并排序(Merge Sort)实现的排序算法,保持相等元素的相对顺序。时间复杂度为 O(NlogN)
//	bubbleSort(numbers);//冒泡排序的平均时间复杂度为 O(N^2)
//	selectionSort(numbers);//选择排序的时间复杂度为 O(N^2)
//    insertionSort(numbers);//插入排序的时间复杂度为 O(N^2)
//	quickSort(numbers,0,numbers.size());vector<int> temp(numbers.size());merge_sort(numbers, 0, numbers.size(), temp);std::cout << "Sorted numbers: ";for (int num : numbers) {std::cout << num << " ";}std::cout << std::endl;return 0;
}

是否稳定

  1. 稳定的排序算法

    • 冒泡排序(Bubble Sort)
    • 插入排序(Insertion Sort)
    • 归并排序(Merge Sort)
    • 基数排序(Radix Sort)
  2. 不稳定的排序算法

    • 选择排序(Selection Sort)
    • 快速排序(Quick Sort)
    • 堆排序(Heap Sort)
    • 希尔排序(Shell Sort)

时间复杂度

  • 冒泡排序、插入排序、选择排序的时间复杂度为 O(n^2)。
  • 归并排序、快速排序、堆排序的平均时间复杂度为 O(n log n)。
  • 基数排序的时间复杂度为 O(d * (n + k))

空间复杂度

空间复杂度是指算法在运行过程中所需要的额外的存储空间大小。以下是几种常见排序算法的空间复杂度:

  1. 冒泡排序(Bubble Sort):空间复杂度为 O(1),因为只需要常数级别的额外空间用于交换元素。

  2. 插入排序(Insertion Sort):空间复杂度为 O(1),因为只需要常数级别的额外空间用于交换元素。

  3. 选择排序(Selection Sort):空间复杂度为 O(1),因为只需要常数级别的额外空间用于交换元素。

  4. 归并排序(Merge Sort):归并排序是一种分治算法,在归并过程中需要额外的空间来存储临时数组,所以空间复杂度为 O(n)。

  5. 快速排序(Quick Sort):快速排序是一种原地排序算法,通常不需要额外的空间,但是如果使用递归实现,则需要系统栈来存储递归调用的上下文,因此空间复杂度在最坏情况下可能达到 O(n),平均情况下为 O(log n)。

  6. 堆排序(Heap Sort):堆排序是一种原地排序算法,不需要额外的空间,因此空间复杂度为 O(1)。

  7. 希尔排序(Shell Sort):希尔排序是一种改进的插入排序算法,空间复杂度取决于间隔序列的选择,一般为 O(1) 到 O(n)。

  8. 基数排序(Radix Sort):基数排序需要额外的空间来存储桶,空间复杂度取决于数据的范围和位数,一般为 O(n + k),其中 n 是数组长度,k 是数据的范围。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/749391.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

突破编程_C++_查找算法(插值查找)

1 算法题 &#xff1a;使用插值查找算法在有序数组中查找指定元素 1.1 题目含义 使用插值查找算法在有序数组中查找指定元素。插值查找是介于线性查找和二分查找之间的一种查找算法&#xff0c;它是基于二分查找的改进算法。插值查找的核心思想在于根据待查找元素的值在有序数…

Web前端依赖版本管理最佳实践

本文需要读者懂一点点前端的构建知识&#xff1a; 1. package.json文件的作用之一是管理外部依赖&#xff1b;2. .npmrc是npm命令默认配置&#xff0c;放在工程根目录。 Web前端构建一直都是一个不难&#xff0c;但是非常烦人的问题&#xff0c;在DevOps、CI/CD领域。 烦人的是…

Java的SPI机制与实例

Java的SPI机制与实例 是什么&#xff1f; SPI是一种JDK内置的服务提供发现的机制&#xff0c;能够启动框架扩展和替换组件&#xff0c;主要是被框架的开发人员使用&#xff0c;比如java.sql。Driver接口。Java机制的核心思想就是将装配的控制权转移到Java之外&#xff0c;核心…

HTTPS证书很贵吗?

首先&#xff0c;我们需要明确一点&#xff0c;HTTPS证书的价格并不是一成不变的&#xff0c;它受到多种因素的影响。其中最主要的因素包括证书的类型、颁发机构以及所需的验证级别。 从类型上来看&#xff0c;HTTPS证书主要分为单域名证书、多域名证书和通配符证书。单域名证书…

远程过程调用-buttonrpc源码解析1-序列化

分析buttonrpc中的序列化 源码提供了StreamBuffer类&#xff0c;该类继承自vector<char>&#xff0c;用来存储数据。 // 此处省略实现... class StreamBuffer : public vector<char> {};并提供了Serializer类&#xff0c;用来序列化数据。 // 此处省略部分实现..…

pta上的几个例题

c语言中的小小白-CSDN博客c语言中的小小白关注算法,c,c语言,贪心算法,链表,mysql,动态规划,后端,线性回归,数据结构,排序算法领域.https://blog.csdn.net/bhbcdxb123?spm1001.2014.3001.5343 给大家分享一句我很喜欢我话&#xff1a; 知不足而奋进&#xff0c;望远山而前行&am…

1258:【例9.2】数字金字塔-----动态规划(递推)1

题目网址 1258&#xff1a;【例9.2】数字金字塔 首先解这道题我们第一眼想到是不是暴力&#xff0c;但是暴力的话是O(n!)的时间复杂度&#xff0c;很明显&#xff0c;会超时。那怎么办呢&#xff1f;不如我们把他分成若干子问题把&#xff0c;就像分治那样。 首先我们想得到答案…

vue2 项目中使用clipboard复制插件

需求&#xff0c;点击页面中的某一个按钮&#xff0c;复制文字。 npm install clipboard --save 在组件中使用 import Clipboard from clipboard html中的按钮 <div ref"main" class"main"><button click"copy">copy</button…

Android Studio实现内容丰富的安卓校园新闻浏览平台

获取源码请点击文章末尾QQ名片联系&#xff0c;源码不免费&#xff0c;尊重创作&#xff0c;尊重劳动 项目编号070 1.开发环境android stuido jdk1.8 eclipse mysql tomcat 2.功能介绍 安卓端&#xff1a; 1.注册登录 2.查看新闻列表 3.查看新闻详情 4.评论新闻 5.收藏新闻 6…

解决VMware无法检测此光盘映像中的操作系统

今天我本想在VMware上安装一个win10系统&#xff0c;可是遇到“无法检测此光盘映像中的操作系统。您需要指定要安装的操作系统。”的错误。报错如下&#xff1a; 图一 遇到的问题 开始还以为是ISO文件有问题&#xff0c;重新下载了几个还是不行&#xff08;一个ISO文件好几个G&…

免费SSL证书Let‘sEncrypt安装

1. Let’sEncrypt说明&#xff1a; Lets Encrypt 是免费、开放和自动化的证书颁发机构由Linux基金会(Linux Foundation)进行日常管理维护&#xff0c;它为36.3亿个网站提供TLS证书的非盈利性证书颁发机构, 通过它我们可以免费申请网站证书&#xff0c;并您的网站上启用 HTTPS …

APP专项测试

一、介绍 APP测试除了功能测试外&#xff0c;还需要进行一些专项测试来发现更为深层的问题&#xff0c;这些问题主要是针对某个特殊方面进行&#xff0c;如安装卸载升级测试、兼容性测试、弱网测试、中断测试、流量测试、耗电量测试等。 二 、安装卸载升级测试 APP开发后&am…

联想拯救者刃7000K2024游戏电脑主机仅售6999元

这款联想拯救者刀锋7000K 2024游戏电脑主机在京东促销中售价仅为6999元&#xff0c;相比原价7499元有相当大的折扣。 这是一款功能强大的游戏电脑&#xff0c;配备了全新的 15-14400(F) 处理器和 RTX™ 4060 显卡&#xff0c;以及 16GB DDR5 内存和 1TB 固态硬盘。 外观方面&a…

如何有效地组织和管理自己的代码?

如何有效地组织和管理自己的代码&#xff1f; &#x1f9e9; &#x1f6e0;️ 如何有效地组织和管理自己的代码&#xff1f; &#x1f9e9;摘要引言正文1. 使用合适的目录结构2. 模块化设计3. 命名规范4. 版本控制 总结参考资料 博主 默语带您 Go to New World. ✍ 个人主页——…

3.Redis命令

Redis命令 Redis 根据命令所操作对象的不同&#xff0c; 可以分为三大类&#xff1a; 对 Redis 进行基础性操作的命令&#xff0c;对 Key 的操作命令&#xff0c;对 Value 的操作命令。 1.1 Redis 首先通过 redis-cli 命令进入到 Redis 命令行客户端&#xff0c;然后再运行下…

STM32基础--使用寄存器点亮流水灯

GPIO 简介 GPIO 是通用输入输出端口的简称&#xff0c;简单来说就是 STM32 可控制的引脚&#xff0c;STM32 芯片的 GPIO 引脚与外部设备连接起来&#xff0c;从而实现与外部通讯、控制以及数据采集的功能。STM32 芯片的 GPIO被分成很多组&#xff0c;每组有 16 个引脚&#xf…

多源BFS

目录 算法原理 多源BFS步骤&#xff1a; 1、542. 01 矩阵 2、1020. 飞地的数量 3、1765. 地图中的最高点 4、1162. 地图分析 多源BFS&#xff08;Breadth-First Search&#xff0c;广度优先搜索&#xff09;是解决边权为1的多源最短路径问题的有效算法。在这种情况下&…

【模拟string函数的实现】

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 模拟string函数的实现 浅拷贝 深拷贝 vs和g下string结构的说明 总结 前言 模拟string函数的实现 浅拷贝 深拷贝 总结 前言 世上有两种耀眼的光芒&#…

Java面向对象案例之描述专业和学生(4)

类的方法图 学生类&#xff1a; 属性&#xff1a;学号&#xff0c;姓名&#xff0c;年龄&#xff0c;所学习的专业方法&#xff1a;学习的方法&#xff0c;描述学习状态。描述内容包括姓名、学号、年龄、所学习的专业信息 专业类&#xff1a; 属性&#xff1a;专业编号&#xf…

2024年【天津市安全员C证】考试资料及天津市安全员C证考试试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 天津市安全员C证考试资料根据新天津市安全员C证考试大纲要求&#xff0c;安全生产模拟考试一点通将天津市安全员C证模拟考试试题进行汇编&#xff0c;组成一套天津市安全员C证全真模拟考试试题&#xff0c;学员可通过…