C++数据结构X篇_23_快速排序(最快、不稳定的排序)

news2025/1/11 14:03:56

文章参考十大经典排序算法-快速排序算法详解进行整理补充。快速排序是最快的排序方法。
排序思路:分治法-挖坑填数大问题分解为各个小问题,对小问题求解,使得大问题得以解决

文章目录

  • 1. 什么是快速排序
    • 1.1 概念
    • 1.2 算法原理
    • 1.3 算法实现
      • 1.3.1 核心代码
      • 1.3.2 整体代码
  • 2. 快速排序算法特点
    • 2.1 时间复杂度
    • 2.2 空间复杂度
    • 2.3 稳定性

1. 什么是快速排序

1.1 概念

快速排序(Quick Sort)是从冒泡排序算法演变而来的,实际上是在冒泡排序基础上的递归分治法。快速排序在每一轮挑选一个基准元素,并让其他比它大的元素移动到数列一边,比它小的元素移动到数列的另一边,从而把数列拆解成了两个部分。

1.2 算法原理

这是一个无序数列:4、5、8、1、7、2、6、3,我们要将它按从小到大排序。按照快速排序的思想,我们先选择一个基准元素,进行排序。
在这里插入图片描述
我们选取4为我们的基准元素,并设置基准元素的位置为index(可以看做一个坑位,比较后满足条件的就填进去),设置两个指针left和right,分别指向最左和最右两个元素
在这里插入图片描述
接着,从right指针开始,把指针所指向的元素和基准元素做比较,如果比基准元素大,则right指针向左移动,如果比基准元素小,则把right所指向的元素填入index中

3和4比较,3比4小,将3填入index中,原来3的位置成为了新的index,同时left右移一位
在这里插入图片描述
然后,我们切换left指针进行比较,如果left指向的元素小于基准元素,则left指针向右移动,如果元素大于基准元素,则把left指向的元素填入index中

5和4比较,5比4大,将5填入index中,原来5的位置成为了新的index,同时right左移一位
在这里插入图片描述
接下来,我们再切换到right指针进行比较,6和4比较,6比4大,right指针左移一位
在这里插入图片描述
2和4比较,2比4小,将2填入index中,原来2的位置成为新的index,left右移一位
在这里插入图片描述
随着left右移,right左移,最终left和right重合
在这里插入图片描述
此时,我们将基准元素填入index中,这时,基准元素左边的都比基准元素小,右边的都比基准元素大,这一轮交换结束
在这里插入图片描述
第一轮,基准元素4将序列分成了两部分,左边小于4,右边大于4,第二轮则是对拆分后的两部分进行比较

此时,我们有两个序列需要比较,分别是3、2、1和7、8、6、5,重新选择左边序列的基准元素为3,右边序列的基准元素为7
在这里插入图片描述
第二轮排序结束后,结果如下所示
在这里插入图片描述
此时,3、4、7为前两轮的基准元素,是有序的,7的右边只有8一个元素也是有序的,因此,第三轮,我们只需要对1、2和5、6这两个序列进行排序
在这里插入图片描述
第三轮排序结果如下所示
在这里插入图片描述
至此所有的元素都是有序的.

1.3 算法实现

1.3.1 核心代码

//快速排序  升序
void quick_sort(int arr[], int start, int end)
{
	int i = start;
	int j = end;
	int temp = arr[start];//基准数
	if (i < j)
	{
		while (i < j)
		{
			//从右往左找比基准数小的
			while (i < j && arr[j] >= temp)
			{
				j--;
			}
			//填坑
			if (i < j)
			{
				arr[i] = arr[j];
				i++;
			}
			//从左向右找比基准数大的数
			while (i < j && arr[i] < temp)
			{
				i++;
			}
			//填坑
			if (i < j)
			{
				arr[j] = arr[i];
				j--;
			}
		}
		//基准数放入i=j中
		arr[i] = temp;
		//对基准数左半部分快速排序
		quick_sort(arr, start, i - 1);
		//对基准数右半部分快速排序
		quick_sort(arr, j + 1, end);
	}

}

1.3.2 整体代码

#include <iostream>
using namespace std;

void swap(int* a, int* b)
{
	int temp = *a;
	*a = *b;
	*b = temp;
}

//打印数组
void printArr(int arr[])
{
	for (int i = 0; i < 10; i++)
	{
		cout << arr[i] << endl;
	}
}

//快速排序  升序
void quick_sort(int arr[], int start, int end)
{
	int i = start;
	int j = end;
	int temp = arr[start];//基准数
	if (i < j)
	{
		while (i < j)
		{
			//从右往左找比基准数小的
			while (i < j && arr[j] >= temp)
			{
				j--;
			}
			//填坑
			if (i < j)
			{
				arr[i] = arr[j];
				i++;
			}
			//从左向右找比基准数大的数
			while (i < j && arr[i] < temp)
			{
				i++;
			}
			//填坑
			if (i < j)
			{
				arr[j] = arr[i];
				j--;
			}
		}
		//基准数放入i=j中
		arr[i] = temp;
		//对基准数左半部分快速排序
		quick_sort(arr, start, i - 1);
		//对基准数右半部分快速排序
		quick_sort(arr, j + 1, end);
	}

}

int main()
{
	int arr[] = { 8,2,3,9,6,4,7,1,5,10 };
	quick_sort(arr,0,9);
	printArr(arr);
	system("pause");
	return 0;
}

运行结果:
在这里插入图片描述

2. 快速排序算法特点

2.1 时间复杂度

快速排序算法在分治法的思想下,原数列在每一轮被拆分成两部分,每一部分在下一轮又分别被拆分成两部分,直到不可再分为止,平均情况下需要logn轮,因此快速排序算法的平均时间复杂度是O(nlogn)

在极端情况下,快速排序算法每一轮只确定基准元素的位置,时间复杂度为O(N^2)

2.2 空间复杂度

快速排序算法排序过程中只是使用数组原本的空间进行排序,因此空间复杂度为O(1)

2.3 稳定性

快速排序算法在排序过程中,可能使相同元素的前后顺序发生改变,所以快速排序是一种不稳定排序算法

  1. 快速排序1,快速排序2,参考博文:常见的几种排序(C++)

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

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

相关文章

淘宝商品链接获取淘宝商品评论数据(用 Python实现淘宝商品评论信息抓取)

在网页抓取方面&#xff0c;可以使用 Python、Java 等编程语言编写程序&#xff0c;通过模拟 HTTP 请求&#xff0c;获取淘宝多网站上的商品详情页面评论内容。在数据提取方面&#xff0c;可以使用正则表达式、XPath 等方式从 HTML 代码中提取出有用的信息。值得注意的是&#…

android10.0(Q)编译安卓内核(pixel 2)

下载内核源码 1.查看内核版本 首先需要看一下内核的版本&#xff0c;可以在手机中看到内核版本 2.下载该内核版本对应的源码 cd ~/mount/project/androidq git clone https://aosp.tuna.tsinghua.edu.cn/android/kernel/msm.git cd msm git checkout 4fecde07e68d执行结果如…

Python之作业(三)

Python之作业&#xff08;三&#xff09; 练习题 给出3个整数&#xff0c;使用if语句判断大小&#xff0c;并升序输出有一个列表lst [1,4,9,16,2,5,10,15],生成一个新列表&#xff0c;要求新列表元素是lst相邻2项的和随机生成100个产品ID&#xff0c;ID格式如下 顺序的数字6…

SD-WAN跨境网络专线|跨境访问无忧!让海外SaaS平台与视频会议更稳定轻松的解决方案

在现如今全球化的时代&#xff0c;企业都有布局全球或是有潜力的国家&#xff0c;在海外开分公司必不可少&#xff0c;那与海外合作伙伴进行沟通与合作已经成为企业的常态。但是&#xff0c;访问海外的SaaS平台和进行视频会议时&#xff0c;我们经常会遇到网络不稳定、速度慢的…

m1 安装 cocoapods

其实最终解决问题很简单&#xff0c;麻烦的是如果找到解决问题的答案。 网上的答案一大堆&#xff0c;但不一定适合你的电脑&#xff0c;就好像天下的女人到处有&#xff0c;但不一定都适合你&#xff0c;一定要亲自试验一下才知道结果。 前提条件&#xff1a; 命令行工具&am…

Dunham‘s sports EDI需求分析

Dunhams Sports&#xff0c;成立于1937年&#xff0c;是美国领先的运动用品零售商之一。公司总部位于密歇根州&#xff0c;致力于提供广泛的体育用品和户外装备。Dunhams Sports的使命是为顾客提供最优质的运动体验&#xff0c;他们以卓越的服务和品质&#xff0c;赢得了无数荣…

【访问控制】—>《熟练使用ACL进行上网行为管理》

✍ 标准和高级ACL功能介绍&#xff1b; ✍ 思科和华为ACL功能有什么区别&#xff1f; ✍ 现网中ACL都有哪些使用场景&#xff1f; -- ACL - 访问控制列表 - 控制&#xff1a; 能通/不能通 -- ACL - 结合功能 list - 简化版本的行为管理 -- 插件性质的功能 --…

echarts 仪表盘统计图

<!--仪表盘统计图--><div class"ybptx" ref"btryzb"></div>mounted(){this.getBtData();}getBtData() {let chart this.$echarts.init(this.$refs.btryzb);let data_czzf this.cznlzhpj.czzfs;let option {series: [{name: 内层数据刻…

水表能实时监测哪些参数?

你是否曾经想过&#xff0c;你家的水表是如何工作的?它不仅能够记录你的用水量&#xff0c;还能实时监测一些重要的参数&#xff0c;比如水压、水温、水质等。这些参数对于保证用水安全和节约用水资源都有着重要的作用。接下来&#xff0c;小编就来为大家详细的介绍下水表能实…

java中的数据源

为什么要使用数据源 jdbc是什么 JDBC 就是使用Java语言操作关系型数据库的一套API&#xff0c;我们开发的同一套Java代码是无法操作不同的关系型数据库&#xff0c;因为每一个关系型数据库的底层实现细节都不一样。如果这样&#xff0c;问题就很大了&#xff0c;在公司中可以在…

虚拟机Ubuntu - 环境配置

文章目录 安装虚拟机安装必要工具修改IP地址修改主机名安装Java方法一&#xff1a;apt 安装方法二&#xff1a;使用PPA仓库&#xff08;适用于Ubuntu 18.04以上版本&#xff09; 远程连接另一台宿主机的虚拟机方法一&#xff1a;NAT连接方法二&#xff1a;桥连接&#xff08;推…

selenium判断元素可点击、可见、可选

1、判断元素是否可以点击 判断元素是否可以点击&#xff0c;WebElement对象调用is_enabled() is_enabled()方法返回一个布尔值&#xff0c;若可点击返回&#xff1a;True。若不可点击则返回&#xff1a;False from selenium import webdriver import time from selenium.web…

LeetCode 热题 100 - 第1题:两数之和

LeetCode 热题 100 - 第1题:两数之和 原题题目理解普通的解题思路---遍历查找进阶的解题思路---哈希查找 原题 给定一个整数数组 nums和一个整数目标值target&#xff0c;请你在该数组中找出 和为目标值 target的那两个整数&#xff0c;并返回它们的数组下标。 你可以假设每种…

Docker 镜像常用命令总结

目录 1. Docker镜像相关命令(重点掌握) 1.1 docker pull 镜像名称 [:tag] 拉取镜像 1.2 docker search 镜向名称 (查询某个镜像) 1.3 docker images 列出当前主机上所有镜像 1.4 docker rmi 镜像ID 删除镜像 1.5 docker system df 查看所有镜像容器所占空间 2. Docker …

每日一练——快速合并2个有序数组

每日一练来喽~~~ 今天up主为大家分享一个&#xff0c;快速合并2个有序数组的法子&#xff0c;注意听哟&#xff01; 题目&#xff1a; 给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2&#xff0c;另有两个整数 m 和 n &#xff0c;分别表示 nums1 和 nums2 中的元素数…

2、TB6600驱动器介绍【51单片机控制步进电机-TB6600系列】

摘要&#xff1a;本节介绍TB6600驱动器界面及关键参数设置 一、驱动器功能界面 二、关键参数 输入电压&#xff1a;DC9-42V 输出电流&#xff1a;0.5-4A 最大功耗&#xff1a;160W 细分设置&#xff1a;1,2/A,2/B,4,8,16,32 工作温度&#xff1a;-10~45C 信号口驱动电流&…

用ST-LINK 出现连接失败【已解决】

出现的问题&#xff1a;not connect to target! 13:33:39 : Can not connect to target! Please select "Connect Under Reset" mode from Target->Settings menu and try again. If youre trying to connect to a low frequ…

【Java集合类面试二十七】、谈谈CopyOnWriteArrayList的原理

文章底部有个人公众号&#xff1a;热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享&#xff1f; 踩过的坑没必要让别人在再踩&#xff0c;自己复盘也能加深记忆。利己利人、所谓双赢。 面试官&#xff1a;谈谈CopyOnWriteArrayLi…

FlutterUnit 周边 | 收录排序算法可视化

theme: cyanosis 1. FlutterUnit 更新&#xff1a;排序算法可视化 排序算法可视化是用视图层表现出算法执行过程中排序的过程&#xff0c;感谢 编程的平行世界 在 《十几种排序算法的可视化效果&#xff0c;快来看看&#xff01;&#x1f440;》》 一文中提供的算法支持。我进行…

【Proteus仿真】【Arduino单片机】继电器和按键

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真Arduino单片机控制器&#xff0c;使用蜂鸣器、按键、继电器、电机等。 主要功能&#xff1a; 系统运行后&#xff0c;K1键控制蜂鸣器发声&#xff0c;K2键控制LED开关&#xff0c;…