归并排序与快速排序总结-c++

一,归并排序

归并排序(Merge sort)是建立在归并操作上的一种有效的排序算法。该算法分治法(Divide and Conquer)的一个非常典型的应用。

作为一种典型的分而治之思想的算法应用,归并排序的实现由两种方法:

1.自上而下的递归(所有递归的方法都可以用迭代重写)
2.自下而上的迭代
1.基本思想

归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。

在这里插入图片描述
简而言之,先通过递归的思想将数组分成一个一个的不可再分的子序列,接下来再对其中两个子序列按照升序或者降序合并,重复直到合并所有子序列合并完成。(子问题其实就是两个有序数组的合并)。

2.程序实现
#include<iostream>
using namespace std;
#define eleType int//合并两个有序子序列
/*
参数含义: arr数组, left:序列的左边起始点 mid:中间下标 right:右边结束点
通过left mid right 将arr分成左右两个区域
*/
void merge(eleType *arr,int left,int mid,int right){int i = left, j = mid + 1;  // i为左边区域的指针 j 为右边区域的指针eleType *temp = new eleType[right + 1]; //临时数组,用来临时存放排序后的数字int index = 0; //临时数组的下标while(i <= mid && j <= right){ //当左右区域都有未比完的数字temp[index++] = arr[i] < arr[j] ? arr[i++] : arr[j++]; //选择较小的存入temp数组}while(i <= mid){ //当仅剩左边区域temp[index++] = arr[i++]; // 按顺序存入temp}while(j <= right){ //当仅剩右边区域temp[index++] = arr[j++]; //按顺序存入temp}for(int i = 0; i < index; i++){ //将temp重新放回arrarr[left + i] = temp[i];}delete [] temp; //删除临时temp数组
}
//归并排序
/* 参数含义: left:最左边下标  right : 最右边的下标通过left 和right 计算出中间数的下标
*/
void mergesort(eleType *arr,int left,int right){if(left < right){ //递归条件int mid = left + (right - left) / 2; //计算中间下标mergesort(arr,left,mid); //递归划分左边区域mergesort(arr,mid + 1, right);//递归划分右区域merge(arr,left,mid,right); //执行合并}
}
3.优缺点:

优点
稳定性: 稳定的排序算法,即相同元素的相对顺序在排序前后保持不变。
最佳、平均和最坏时间复杂度:归并排序在所有情况下(包括输入数组已排序或逆序)的时间复杂度都是O(n log n),n是数组的大小。它在处理大数据集时非常高效。
空间复杂度:虽然归并排序需要额外的空间来存储临时子数组,但它的空间复杂度是O(n),在实际应用中通常是可以接受的。
缺点
空间复杂度:虽然O(n)的空间复杂度可以接受的,但对于内存受限的环境或需要就地排序的场合,归并排序不是最佳选择。
数据移动次数:归并排序在合并过程中可能需要大量的数据移动操作,这可能导致在某些情况下效率较低。
不适合小数据集:对于非常小的数据集,归并排序的额外空间开销和递归调用相对于其他简单排序算法效率较低。但是在大数据集上,归并排序的O(n log n)时间复杂度远优于这些简单排序算法。
递归深度:归并排序是递归算法,对于非常大的数据集,递归深度可能会很大,可能导致栈溢出。

二,快速排序

1.基本思想

通过一次排序将待排序的数据分割成独立的两部分,其中一部分的所有数据都比另一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
在这里插入图片描述

2.实现步骤
  • 1.选择一个基准元素(pivot):通常选择待排序序列的第一个或最后一个元素作为基准。
  • 2.分割过程:将序列中小于基准的元素放在基准的左边,大于基准的元素放在基准的右边。这个过程称为分区(partition)操作,分区结束后基准元素所处的位置就是其在已排序序列中的正确位置。
  • 3.递归排序:分别对基准左右两边的子序列进行快速排序。
3.代码实现
#include<iostream>
using namespace std;
#define eleType int
/* 划分 将比基准数大的放右边,比基准数小的放左边
参数含义: arr数组,left:最左边的下标 right: 最右边的下标
*/int getKeyPositon(eleType *arr,int left,int right){int key = arr[left]; //将第一个数作为基准数while(left < right){while(arr[right] >= key && left < right){ //右边先移动,找比基准数小的right--;}arr[left] = arr[right]; //找到之后赋值给左边left的位置while(arr[left] <= key && left < right){ //之后左边移动,找比基准数大的left++;}arr[right] = arr[left];//找到之后赋值给右边right的位置}arr[left] = key; //左右指针相遇之后,将基准数放回相遇的位置return left; //返回基准数的位置
}
/*
排序过程,不停的基准数放到正确位置
参数含义: arr数组,left:最左边的下标 right: 最右边的下标
*/
void quickSort(eleType *arr,int left,int right){if(left < right){ //递归条件int position = getKeyPositon(arr,left,right); //基准数归位之后,数组被分成左右两部分quickSort(arr,left,position - 1); //对左边部分排序quickSort(arr,position + 1,right); //对右边部分排序}
}
优缺点

优点:
速度快:在平均情况下,快速排序的时间复杂度为O(n log n),比许多排序算法都要快。
原地排序:只需要一个很小的栈空间来保存递归的调用,不需要额外的存储空间。
缺点:
最坏情况:在最坏情况下(输入数据已经有序或接近有序),快速排序的时间复杂度会退化到O(n^2)。
空间复杂度:虽然快速排序是原地排序,但在递归调用时可能会占用较大的栈空间。对于非常大的数据集,会导致栈溢出。
对基准元素的选择敏感:基准元素的选择会影响到排序的性能。如果每次选择的基准元素都是序列中最小或最大的元素,排序的效率就会降低。

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

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

相关文章

KVM网络模式设置

一、KVM网络模式介绍 1、NAT ( 默认上网 ) 虚拟机利用host机器的ip进行上网,对外显示一个ip;virbr0是KVM 默认创建的一个 Bridge,其作用是为连接其上的虚机网卡提供NAT访问外网的功能,默认ip为192.168.122.1 2、自带的Bridge 将虚拟机桥接到host机器的网卡上,vm和ho…

mysql如何一句实现二行数据的列对换?

二行数据相同列内容对换 思路&#xff1a;先用多表联查的方式查询出这二行数据&#xff0c;再将查询改成修改语句&#xff0c;需要对换的列相互设置值。 //查询 SELECT * fromser_ele_detail AS rule1JOIN ser_ele_detail AS rule2 ON ( rule1.account_no rule2.account_no …

240622_昇思学习打卡-Day4-ResNet50迁移学习

240622_昇思学习打卡-Day4-ResNet50迁移学习 我们对事物的认知都是一点一点积累出来的&#xff0c;往往借助已经认识过的东西&#xff0c;可以更好地理解和认识新的有关联的东西。比如一个人会骑自行车&#xff0c;我们让他去骑摩托车他也很快就能学会&#xff0c;比如已经学会…

使用容器部署redis_设置配置文件映射到本地_设置存储数据映射到本地_并开发java应用_连接redis---分布式云原生部署架构搭建011

可以看到java应用的部署过程,首先我们要准备一个java应用,并且我们,用docker,安装一个redis 首先我们去start.spring.io 去生成一个简单的web项目,然后用idea打开 选择以后下载 放在这里,然后我们去安装redis 在公共仓库中找到redis . 可以看到它里面介绍说把数据放到了/dat…

FLASH闪存

FLASH闪存 程序现象&#xff1a; 1、读写内部FLASH 这个代码的目的&#xff0c;就是利用内部flash程序存储器的剩余空间&#xff0c;来存储一些掉电不丢失的参数。所以这里的程序是按下K1变换一下测试数据&#xff0c;然后存储到内部FLASH&#xff0c;按下K2把所有参数清0&…

找不到mfc140u.dll怎么修复,mfc140u.dll丢失的多种修复方法

计算机丢失mfc140u.dll文件会导致依赖该文件的软件无法正常运行。mfc140u.dll是Microsoft Visual C 2015的可再发行组件之一&#xff0c;它属于Microsoft Foundation Class (MFC) 库&#xff0c;许多使用MFC开发的程序需要这个DLL文件来正确执行。丢失了mfc140u.dll文件。会导致…

无人机无刷电机理论教学培训课程

本文档为一份关于Brushless电机理论的详细教程&#xff0c;由TYTO Robotics编制&#xff0c;旨在帮助用户理解brushless电机的工作原理、特性以及如何通过实验测定其关键参数Kv和Kt。文档首先介绍了brushless电机的基本组成&#xff0c;包括静止的定子和旋转的转子&#xff0c;…

考研数学|线代零基础,听谁的课比较合适?

线性代数是数学的一个重要分支&#xff0c;对于考研的学生来说&#xff0c;掌握好这门课程是非常关键的。由于你之前没有听过线性代数课&#xff0c;选择一个合适的课程和老师就显得尤为重要。 以下是一些建议&#xff0c;希望能帮助你找到合适的课程资源。 首先&#xff0c;…

Hadoop3:MapReduce中的ETL(数据清洗)

一、概念说明 “ETL&#xff0c;是英文Extract-Transform-Load的缩写&#xff0c;用来描述将数据从来源端经过抽取&#xff08;Extract&#xff09;、转换&#xff08;Transform&#xff09;、加载&#xff08;Load&#xff09;至目的端的过程。ETL一词较常用在数据仓库&#…

LED显示屏的点间距越小越好吗

引言 在LED显示屏市场日趋成熟的同时&#xff0c;小间距显示屏成为了许多用户的首选。然而&#xff0c;点间距真的是越小越好吗&#xff1f;本文将探讨这一问题&#xff0c;并提供全面的选购指南。 点间距&#xff1a;并非越小越好 小间距显示屏因其精细的显示效果而备受青睐。…

剪辑如何剪辑制作视频短视频剪辑学习怎么学,难吗?

工欲善其事必先利其器&#xff0c;有一个好的工具能让你的工作如鱼得水&#xff0c;果你想在短视频中制作精良的视频&#xff0c;你就考虑电脑制作软件了。果你想制作精良的视频&#xff0c;你就考虑电脑制作软件了。 如何找到剪辑软件了&#xff1f;你可以直接去软件的官方。你…

KT6368A-sop8蓝牙主机芯片获取电动车胎压传感器数据功能

KT6368A蓝牙芯片新增主机模式&#xff0c;扫描周边的胎压传感器&#xff0c;这里扮演的角色就是观察者。因为测试胎压传感器&#xff0c;发现它的广播模式可发现&#xff0c;不可连接 胎压传感器部分的手册说明如下&#xff0c;关于蓝牙部分的协议 实际蓝牙芯片收到的数据&…

Studying-代码随想录训练营day20| 235.二叉搜索树的最近公共祖先、701.二叉搜索树中的插入操作、450.删除二叉搜索树中的节点

第二十天&#xff0c;二叉树part07&#xff0c;二叉树搜索树加油加油&#x1f4aa; 目录 235.二叉搜索树的最近公共祖先 701.二叉搜索树中的插入操作 450.删除二叉搜索树中的节点 拓展&#xff1a;普通二叉树的删除方式 总结 235.二叉搜索树的最近公共祖先 文档讲解&…

洁净室(区)浮游菌检测标准操作规程及GB/T 16292-2010测试方法解读

洁净室(区)空气中浮游菌的检测。洁净区浮游菌检测是一种评估和控制洁净区(如实验室、生产车间等)内空气质量的方法。这种检测的目的是通过测量空气中的微生物(即浮游菌)数量&#xff0c;来评估洁净区的清洁度或污染程度。下面中邦兴业小编带大家详细看下如何进行浮游菌采样检测…

RK3568技术笔记九 编译Linux详细介绍

在编译前需要按照前面的方法始化编译环境&#xff0c;否则会导致编译失败&#xff08;若配置过则无需重复配置&#xff09;。 全自动编译包含所有镜像编译&#xff0c;包括&#xff1a;uboot编译、Kernel编译、Recovey编译、文件系统编译、编译完成镜像的更新与打包。 按照前面…

阅读笔记——《Large Language Model guided Protocol Fuzzing》

【参考文献】Meng R, Mirchev M, Bhme M, et al. Large language model guided protocol fuzzing[C]//Proceedings of the 31st Annual Network and Distributed System Security Symposium (NDSS). 2024.&#xff08;CCF A类会议&#xff09;【注】本文仅为作者个人学习笔记&a…

2024ciscn 华东北awdp pwn部分wp

pwn1 break 很简单&#xff0c;栈可执行。 先格式化字符串泄露出栈地址和canary&#xff0c;然后稍稍布置一下打orw就行 沙盒和没有一样 from pwn import *context(archamd64, oslinux)if __name__ __main__:# io remote(192.47.1.39, 80)io remote(192.168.142.137, 123…

初阶 《操作符详解》 10. 逗号表达式

10. 逗号表达式 exp1, exp2, exp3, …expN 注&#xff1a; 1.逗号表达式&#xff0c;就是用逗号隔开的多个表达式 2.逗号表达式&#xff0c;从左向右依次执行&#xff0c;整个表达式的结果是最后一个表达式的结果 代码1 #include <stdio.h> int main() {int a 1;int b…

解决ubuntu18.04 安装vscode 报依赖库错误,以及打不开终端的问题。

其实很简单&#xff0c;ubuntu18.04太老了&#xff0c;官网最新版本的vscode对ubuntu18.04会有些依赖库的问题。 一顿查资料后发现2023.11月的1.85版本正常使用&#xff0c;于是完美解决。 下载链接 Visual Studio Code November 2023 点击这里下载。 下载完成&#xff0c;…

数据结构需要每个都具体实现吗?

在开始前刚好我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「数据结构的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“666”之后私信回复“666”&#xff0c;全部无偿共享给大家&#xff01;&#xff01;&#xff01;用c的stl能刷算法题是不…