C++基础算法④——排序算法(快速、归并附完整代码)

快速排序

快速排序是对冒泡排序的一种改进。
它的基本思想是:通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录继续进行快速排序,以达到整个序列有序。
假设我们现在对 6 1 2 7 9 3 4 5 1 0 8 这个10个数进行排序。

int main(){int n;cin>>n;for(int i=1;i<=n;i++) cin>>a[i];qsort(1,n);for(int i=1;i <=n;i++){cout<<a[i]<<" ";}	return 0;
}

首先在这个序列中随便找一个数作为基准数(不要被这个名词吓到了,就是一个用来参照的数)。为了方便,就让第一个数6作为基准数吧。接下来,需要将这个序列中所有比基准数大的数放在6的右边,比基准数小的数放在6的左边,类似下面这种排列:

int a[10001];
void qsort(int l,int r){int i,j,mid;i=l+1,j=r;mid=a[l];

在这里插入图片描述
可以发现,i从第二个位置开始,j从最后一个位置开始;当 i 指向的值 大于基准值6 而且 当 j 指向的值 小于基准值6,就把这两个值交换,然后接着往下继续比。
在这里插入图片描述

while(i<=j){ //当 i j 没有碰到while(a[i]<mid) i++;while(a[j]>mid) j--;if(i<=j){swap(a[i],a[j]);i++; j--;}}

在这里插入图片描述
当 i j 相遇了,就把 j指向的值 与基准数交换。

swap(a[j],a[l]); //交换基准数

在这里插入图片描述
可以发现,一趟完毕,原基准数6的左边值一定比6小,右边比6大。这样就确定了基准数6的排序。
接下来,对于6左边的序列3 1 2 5 4和右边的序列9 7 10 8分别进行快速排序。
把整体分了左右边,再把左边的序列3 1 2 5 4看成新的重新进行快速排序。不断地分解。
在这里插入图片描述
所以这个排序运用了分治的思想!
完整代码:

#include<bits/stdc++.h>
using namespace std;
int a[10001];
void qsort(int l,int r){int i,j,mid;i=l+1,j=r;mid=a[l];while(i<=j){while(a[i]<mid) i++;while(a[j]>mid) j--;if(i<=j){swap(a[i],a[j]);i++; j--;}}swap(a[j],a[l]); //交换基准数if(l<j) qsort(l,j-1);if(i<r) qsort(i,r); 
}
int main(){int n;cin>>n;for(int i=1;i<=n;i++) cin>>a[i];qsort(1,n);for(int i=1;i <=n;i++){cout<<a[i]<<" ";}	return 0;
}

快速排序是不稳定的排序方法,时间复杂度是O(nlog2n),速度快,平均时间来说,快速排序是最好的一种内部排序方法。但快速排序需要一个栈空间实现递归,每一趟排序都会将记录序列分割成两个子序列,栈最大深度为log(n+1)。


归并排序

归并的思路(分治)是把一个大问题a拆解成两个小问题b和c,解决了两个子问题再整合一下,就解决了原问题。用递归的方法,先分解再合并(分治是一种解决问题的处理思想,递归是一种编程技巧,这两者并不冲突)。

  • 稳定性:稳定;
  • 空间复杂度O(n);
  • 复杂度:时间复杂度O(nlogn);
  • 优缺点:效率高且稳定,但是消耗的辅助空间与原数据空间成正比。
int main(){cin>>n;for(int i=1;i<=n;i++){ //输入 cin>>a[i];}//归并排序mergesort(1,n);for(int i=1;i<=n;i++){ //输出 cout<<a[i]<<" ";}return 0;
}
  1. 递归分解
    在这里插入图片描述
    不断地二分分解,拆左右。
void mergesort(int l,int r){int mid = (l+r)/2;if(l==r) return ;mergesort(l,mid); //左边排序mergesort(mid+1,r);//右边排序//上面已经拆成一个一个 merge(l,mid,mid+1,r); //合并操作 
}

分解到1个值,然后再合并排序。合并的思路看成:左边是有序的a数组;右边是有序的b数组。两数组开始比较,小的值依次存到c数组。

int a[100],c[100],n,cnt;
void merge(int left,int i,int j,int right){int lenc = left;int len1 = left;  //左边开头 看成a[] int len2 = j;  	//右边开头	 看成b[] while(len1<=i && len2<=right){ //并c[] if(a[len1]<a[len2]){ //左边小于右边 c[lenc++] = a[len1++];}else{//右边小于左边c[lenc++] = a[len2++];}} while(len1<=i){c[lenc++] = a[len1++];} while(len2<=right){c[lenc++] = a[len2++];}//把排好序的c数组存回a数组里面for(int k=left;k<=right;k++){a[k]=c[k];} 
} 

完整代码:

#include<bits/stdc++.h>
using namespace std;
int a[100],c[100],n,cnt;
void merge(int left,int i,int j,int right){int lenc = left;int len1 = left;  //左边开头 看成a[] int len2 = j;  	//右边开头	 看成b[] while(len1<=i && len2<=right){ //并c[] if(a[len1]<a[len2]){ //左边小于右边 c[lenc++] = a[len1++];}else{//右边小于左边c[lenc++] = a[len2++];}} while(len1<=i){c[lenc++] = a[len1++];} while(len2<=right){c[lenc++] = a[len2++];}//把排好序的c数组存回a数组里面for(int k=left;k<=right;k++){a[k]=c[k];} 
} void mergesort(int l,int r){int mid = (l+r)/2;if(l==r) return ;mergesort(l,mid); //左边排序mergesort(mid+1,r);//右边排序//上面已经拆成一个一个 merge(l,mid,mid+1,r); //合并操作 
}
int main(){cin>>n;for(int i=1;i<=n;i++){ //输入 cin>>a[i];}//归并排序mergesort(1,n);for(int i=1;i<=n;i++){ //输出 cout<<a[i]<<" ";}return 0;
}

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

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

相关文章

Linux————内置命令大全

&#xff08;一&#xff09;内置命令 Shell 内置命令&#xff0c;就是由 Bash Shell 自身提供的命令&#xff0c;而不是文件系统中的可执行脚本文件。内置命令的执行速度通常优于外部命令&#xff0c;因为执行外部命令不仅会导致磁盘I/O操作&#xff0c;而且还需要为其fork一个…

Android Studio中配置Git

安装Git 在安装Android Studio之前&#xff0c;需要先安装Git。可以从Git官网下载并安装Git&#xff1a;https://git-scm.com/downloads 在Android Studio中配置Git 在Android Studio中&#xff0c;依次点击“File” -> “Settings”&#xff0c;在弹出的窗口中选择“Ver…

设置防火墙

1.RHEL7中的防火墙类型 防火墙只能同时使用一张,firewall底层调用的还是lptables的服务: firewalld:默认 &#xff0c;基于不同的区域做规则 iptables: RHEL6使用&#xff0c;基于链表 Ip6tables Ebtables 2.防火墙的配置方式 查看防火墙状态: rootlinuxidc -]#systemct…

041-第三代软件开发-QCustcomPlot波形标注

第三代软件开发-QCustcomPlot波形标注 文章目录 第三代软件开发-QCustcomPlot波形标注项目介绍QCustcomPlot波形标注效果初始化绘制 关键字&#xff1a; Qt、 Qml、 关键字3、 关键字4、 关键字5 项目介绍 欢迎来到我们的 QML & C 项目&#xff01;这个项目结合了 QML…

精密数据工匠:探索 Netty ChannelHandler 的奥秘

通过上篇文章&#xff08;Netty入门 — Channel&#xff0c;把握 Netty 通信的命门&#xff09;&#xff0c;我们知道 Channel 是传输数据的通道&#xff0c;但是有了数据&#xff0c;也有数据通道&#xff0c;没有数据加工也是没有意义的&#xff0c;所以今天学习 Netty 的第四…

Windows2008系统怎么隐藏或打开文件后缀

打开服务器的控制面板-选择小图标-文件夹选项 在文件夹选项那边点击查看-隐藏一直文件类型的扩展名 选择勾选&#xff08;隐藏一直文件类型的扩展名&#xff09;-下图示文件后缀不显示 选择不勾选&#xff08;隐藏一直文件类型的扩展名&#xff09;-下图示文件后缀显示

自定义元素宽高比例(aspect-ratio)与@supports兼容支持和图片裁剪(object-fit)的用法

使用grid布局可以轻松实现响应式布局&#xff0c;子元素只需要设置最小宽度即可&#xff0c;如果对子元素没有设置高度&#xff0c;那么高度取决于内容的最大值&#xff0c;这样显然是不稳定的&#xff0c;如下图所示&#xff1a; 出现这种问题就造成布局混乱了&#xff0c;可…

5000张照片怎么快速发给别人?分享三个简单的方法!

有的时候我们不得不一次性发送很多图片&#xff0c;一张一张发实在让人头疼&#xff0c;这个时候就需要借助一些图片压缩工具打包成文件压缩包发送。下面介绍了三种好用的方法&#xff0c;一起来看看吧&#xff5e; 方法一&#xff1a;使用微信助手 可以使用微信助手&#xff…

【C++】多态 ⑨ ( vptr 指针初始化问题 | 构造函数 中 调用 虚函数 - 没有多态效果 )

文章目录 一、vptr 指针初始化问题1、vptr 指针与虚函数表2、vptr 指针初始化时机3、构造函数 中 调用 虚函数 - 没有多态效果4、代码示例 构造函数 的 作用就是 创建对象 , 构造函数 最后 一行代码 执行完成 , 才意味着 对象构建完成 , 对象构建完成后 , 才会将 vptr 指针 指向…

对xss-labs靶场的一次XSS攻击

1、首先我们进入靶场&#xff0c;提示我们开始测试 2、我使用AWVS工具进行了先行扫描&#xff0c;发现爆出XSS漏洞 3、然后对症下药 在输入框中输入&#xff1a; <script>alert(document.cookie)</script> 4、进入下一关 5、我们直接执行<script>…

一次cs上线服务器的练习

环境&#xff1a;利用vm搭建的环境 仅主机为65段 测试是否能与win10ping通 配置转发 配置好iis Kali访问测试 现在就用burp抓取winser的包 开启代理 使用默认的8080抓取成功 上线

微服务之负载均衡使用场景

在如见常见微服务系统中&#xff0c;负载均衡组件是一种将流量分配到多个服务的技术&#xff0c;目的是提高系统的性能和可用性。负载均衡有两种常见的模式&#xff1a;服务端模式和客户端模式。服务端模式使用独立的应用程序&#xff08;如 Nginx&#xff09;来转发请求&#…

20.2 OpenSSL 非对称RSA加解密算法

RSA算法是一种非对称加密算法&#xff0c;由三位数学家Rivest、Shamir和Adleman共同发明&#xff0c;以他们三人的名字首字母命名。RSA算法的安全性基于大数分解问题&#xff0c;即对于一个非常大的合数&#xff0c;将其分解为两个质数的乘积是非常困难的。 RSA算法是一种常用…

内网渗透-域信息收集

域环境 虚拟机应用&#xff1a;vmware17 域控主机&#xff1a;win2008 2r 域成员主机&#xff1a;win2008 2r win7 一.域用户和本地用户区别 使用本地用户安装程序时&#xff0c;可以直接安装 使用域用户安装程序时&#xff0c;需要输入域控管理员的账号密码才能安装。总结…

Leetcode.树形DP

目录 543.二叉树的直径 124.二叉树中的最大路径和 2246.相邻字符不同的最长路径 543.二叉树的直径 用递归来写 考虑 树形DP 维护以当前节点为根节点的最大值&#xff0c;同时返回给父节点经过当前节点的最大链的长度&#xff0c;这有个trick 当遍历到空节点的时候返回-1 递归…

Web3公链之Cosmos生态的项目Celestia

文章目录 Web3公链之Cosmos生态的项目&#xff1a;模块化区块链Celestia什么是CelestiaCelestia网络架构数据可用性问题有哪些可用的解决方案&#xff1f; 发展历史运行节点参考 Web3公链之Cosmos生态的项目&#xff1a;模块化区块链Celestia 什么是Celestia 官网&#xff1a…

Go学习第十七章——Gin中间件与路由

Go web框架——Gin中间件与路由 1 单独注册中间件1.1 入门案例1.2 多个中间件1.3 中间件拦截响应1.4 中间件放行 2 全局注册中间件3 自定义参数传递4 路由分组4.1 入门案例4.2 路由分组注册中间件4.3 综合使用 5 使用内置的中间件6 中间件案例权限验证耗时统计 1 单独注册中间件…

驱动day10作业

基于platform驱动模型完成LED驱动的编写 驱动程序 #include <linux/init.h> #include <linux/module.h> #include<linux/platform_device.h> #include<linux/mod_devicetable.h> #include<linux/of.h> #include<linux/of_gpio.h> #inclu…

【CSS】包含块

CSS规范中的包含块 包含块的内容&#xff1a; 元素的尺寸和位置&#xff0c;会受它的包含块所影响。 对于一些属性&#xff0c;例如 width, height, padding, margin&#xff0c;绝对定位元素的偏移值&#xff08;比如 position 被设置为 absolute 或 fixed&#xff09;&…

【原创】java+swing+mysql无偿献血管理系统设计与实现

摘要&#xff1a; 无偿献血管理系统是为了实现无偿献血规范化、有序化、高效化的管理而设计的。本文主要介绍使用java语言开发一个基于C/S架构的无偿献血管理系统&#xff0c;提高无偿献血管理的工作效率。 功能分析&#xff1a; 系统主要提供给管理员、无偿献血人员&#x…