【数据结构】快速排序递归实现 _三种方法详解+优化

19 篇文章 9 订阅
订阅专栏

在这里插入图片描述

常见的排序算法有以上八种,所以预估会分成几期来讲,感兴趣的朋友们不妨点个收藏专栏。 ღ( ´・ᴗ・` )比心

OJ链接


快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法,其基本思想为:

任取待排序元素序列中的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值,然后最左右子序列重复该过程,直到所有元素都排列在相应位置上为止。

将区间按照基准值划分为左右两半部分的常见方式: Hoare法、挖坑法、前后指针法

快排又可以通过递归和非递归的方式进行实现。

Hoare法

在这里插入图片描述

核心思路

  1. 当选择左边的值做key时,右边先走。
  2. 当选择右边的值做key时,左边先走。

本文默认排升序,如图,选择左边值是key。右边先走,找比key小的值停下来,然后左边再走,找到比key大的停下来。交换左右两边的值,知道左右两者相遇。相遇点的值和key值交换。

图例分析

在这里插入图片描述
在这里插入图片描述

单趟程序

// 快速排序hoare版本
int PartSort1(int* a, int left, int right)
{
	// 选择左边的值是key,右边开始走
	int keyi = left;
	while (left < right)
	{
		// left = right的时候,相遇break
		// 右边先走,找小
		while (left < right && a[right] >= a[keyi])
		{
			// 避免下标越界和死循环
			--right;
		}
		// 左边再走,找大
		while (left < right && a[left] <= a[keyi])
		{
			++left;
		}
		// 相遇的值和key交换
		Swap(&a[left], &a[keyi]);
	}
	return left;
}

挖坑法

Hoare版本变形。

核心思路

1、同样的,选择左边的值做key,右边先走;
2、选择右边的值做key,左边先走。

右边找小,把比key小的值放进坑里,右边形成新的坑;左边找大扔到坑里,左边形成新的坑。

在这里插入图片描述

在这里插入图片描述

挖坑法代码

// 快速排序挖坑法
int PartSort2(int* a, int left, int right)
{
	// 选择左边的值做key,右边先走
	int key = a[left];
	int keyi = left;
	while (left < right)
	{
		// 右边先走,找小
		while (left < right && a[right] >= key)
		{
			--right;
		}
		// 找到了小,把小的放进坑里
		a[keyi] = a[right]; // a[right] < key
		keyi = right;

		// 左边再走,找大
		while (left < right && a[left] <= key)
		{
			++left;
		}
		// 找到了大,把大的放进坑里
		a[keyi] = a[left];
		keyi = left;
	}
	// left = right
	// 把keyi值放回坑里
	a[keyi] = key;
	return keyi;
}

前后指针法

在这里插入图片描述

key选择不同,prev和cur的位置也不同。

在这里插入图片描述

当左边的值做key时,cur找比key小的值,找到比key小的值就停下来,++prev,交换prev和cur的值。

在这里插入图片描述

前后指针法程序

// 快速排序前后指针法
int PartSort3(int* a, int left, int right)
{
	// key在left位置
	int keyi = left;
	int prev = left, cur = left + 1;
	while (cur <= right)
	{
		// cur向后找小,找到小的,++prev然后和cur交换
		if (a[cur] < a[keyi] && ++prev != cur)
		{
			Swap(&a[prev], &a[cur]);
		}
		++cur; //cur向后继续找
	}
	// 交换prev和key的值,prev此时是比key小的值
	Swap(&a[prev], &a[keyi]);
	return prev;
}

快排分析+优化

对于理想的快排,每次基准值如下:

在这里插入图片描述

时间复杂度是 O(N*logN)

但是当数组是有序时:

在这里插入图片描述

快排退化成冒泡排序。

解决方法:
1、随机取key值
2、三数取中。

但是三数取中 遇到数组元素相同的情况又会失效。

三数取中:

int GetMidValIndex(int* a, int left, int right)
{
	int mid = left + ((right - left) >> 1);
	if (a[left] < a[mid])
	{
		if (a[mid] < a[right])
		{
			return mid;
		}
		else if (a[left] > a[right])
		{
			return left;
		}
		else
		{
			return right;
		}
	}
	else // a[left] > a[mid]
	{
		if (a[mid] > a[right])
		{
			return mid;
		}
		else if (a[left] < a[right])
		{
			return left;
		}
		else
		{
			return right;
		}
	}
}

快排递归实现

快速排序的递归实现类似二叉树的前序遍历过程。

先使用Hoare、挖坑法或者前后指针法进行单趟排序,再通过递归分别处理左区间和右区间。

void QuickSort(int* a, int left, int right)
{
	if (left >= right)
		return;

	// 小区间优化
	if (right - left + 1 < 10)
	{
		InsertSort(a + left, right - left + 1);
	}
	else
	{	
		int keyi = PartSort3(a, left, right);
		QuickSort(a, left, keyi - 1);
		QuickSort(a, keyi + 1, right);
	}
}

空间复杂度: O(logN)

数据结构】八大排序之快速排序递归和非递归方法
alidada_blog的博客
09-19 2万+
上一博文我们讲了冒泡排序,但是由于他的时间复杂度过高为O(n*n),于是在冒泡排序的基础上今天要说的是快速排序。   本文讲述两个内容: 1.快速排序三种方法。 2.快速排序优化   一.什么是快速排序???      通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递...
快速排序算法递归递归三种方法实现优化
卜及中的博客
03-18 3067
有关快速排序算法的相关问题,三种方式,递归与非递归的代码实现,以及优化
快速排序递归实现
weixin_50168448的博客
01-31 1240
快排思路 绝大多数树的排序算法,都可以先理解每趟排序然后再理解多趟排序,快速排序也不例外。下面我将介绍快速排序中单趟排序的三个方法及思路,分别是 左右指针法,挖坑法,前后指针法。 1.左右指针法 快速排序的每一趟都是为了找出值为key的元素的正确位置。而key是一个随机的元素值。 left是从左往右走找比key大的,right是从右往左走找比key小的。然后交换两个元素的值。 多次寻找后,最终left和right相遇 将相遇位置的元素和key的交换,这样就找到key的正确位置,key的坐左边元素都小
快速排序的分治递归算法
weixin_63289399的博客
03-27 896
快速排序是C.R.A.Hoare于1962年提出的一种划分交换排序,其基本思想是通过一趟扫描将待排序的元素分割成独立的三个序列:第一个序列中所有元素均不大于基准元素、第二个序列是基准元素、第三个序列中所有元素均大于基准元素。由于第二个序列已经处于正确位置,因此需要再按此方法对第一个序列和第三个序列分别进行排序,整个排序过程可以递归进行,最终可使整个序列变成有序序列。 01 问题分析——分与治的方法 (1) 分解:快速排序的分解是基于基准元素的,所以首先要选定一个元素作为基准元素,然后以选定的基
python列表递归排序
最新发布
爆笑蛙的博客
08-28 402
递归排序就是通过不断的从中间位置分割列表,递归一次就分割一次,一直分到分不动位置(只有一个元素或没有元素)。然后比较左右两个元素的大小,按大小顺序重新放到一个列表中;再比较两个有序列表中每一个元素的大小,按照大小顺序再放入一个新的列表中;一直比较有序列表直到第一个递归函数出栈,即可得到一个有序列表。
快速排序递归版本)+python版本
lvjun93的专栏
02-27 750
快速排序 #include<iostream> using namespace std; void swap(int *a,int *b) { int temp=*a; *a=*b; *b=temp; } int partition2(int data[],int low,int high) { int i=low; int j=high; int privot...
Python实现数据结构算法快速排序详解
01-21
本文实例讲述了Python实现数据结构算法快速排序。分享给大家供大家参考。具体分析如下: 一、概述 快速排序(quick sort)是一种分治排序算法。该算法首先 选取 一个划分元素(partition element,有时又称为...
深入单链表的快速排序详解
01-20
然后分别对左、右两个子链表进行递归快速排序,以提高性能。但是,由于单链表不能像数组那样随机存储,和数组的快排序相比较,还是有一些需要注意的细节:1、支点的选取,由于不能随机访问第K个元素,因此每
快速排序的C语言代码
08-11
数据结构中的快速排序实现,用递归实现的C语言快速排序程序。
最快的排序算法 图解八大排序算法——我见过的最详细的讲解(转),排序算法数据结构
04-07
快速排序是一种复杂的排序算法,思路是选择一个元素作为 pivot,然后将数组分成两个部分,小于 pivot 的元素和大于 pivot 的元素,然后对这两个部分进行递归排序。时间复杂度为 O(nlogn),空间复杂度为 O(logn)。 6...
数据结构算法
05-02
8天入门wpf—— 第三天 样式 8天入门wpf—— 第二天 xaml详解 8天入门wpf—— 第一天 基础概念介绍 并行开发(8)8天玩转并行开发——第八天 用VS性能向导解剖你的程序 8天玩转并行开发——第七天 简要分析任务与...
C语言递归实现快速排序
qq_35220609的博客
12-27 1429
快速排序的原理 快速排序(Quicksort)是对冒泡排序的一种改进。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。 快速排序思路 根据快速排序原理,可以用递归方法实现 递归的出口 选择第一个关键字作为标杆(pivot) 定义...
快速排序递归实现
march_on的专栏
09-10 1039
快速排序通常是排序的最佳选择,因为其平均的运行时间为O(nlgn )。最坏情况下每次划分都产生两个分别包含n-1个元素和一个元素的区域,此时时间复杂度为o(n²)。最佳情况下每次划分都将数组分成两个长度差不多的区域,此时时间复杂度与平均性能差不多。        快速排序递归
快速排序递归与非递归实现
qq_39475906的博客
05-16 4835
递归 public class QSort { /** * 找基准 * @param array * @param low * @param high * @return */ public static int partion(int[] array,int low,int high){ int t...
递归实现全排列
qq_41348629的博客
11-11 548
这个程序里有递归,分治算法和散列算法,散列算法我在上上篇讲过,有兴趣的可以看看。 实现123的全排列。 以下 程序建议使用VC实现,DEV还得自己定义bool函数。 #include <stdlib.h> #include <cstdio> const int maxn=11; bool hashTable[maxn]={false}; int n,p[maxn];//全局变量 void generatep(int index) { int i,x; if(index==n+1)
使用递归函数排列
weixin_45783299的博客
04-26 363
加油争取看懂 加油!争取看懂 ## 排列 我们常常要从n个不同元素的所有排列中确定一个最佳的排列。 例如,a. b和c的排列有abc、acb、 bac、 bca、 cba 和cab。n个元素的排列个数是n!。 为输出n个元素的所有排列,编写非递归的C++函数比较困难,但是编写递归函数就 不那么困难了。设E={e,.. en}是n个元素的集合,求E的元素的所有排列。令E表示 从E中去除第i个元素e,以后的集合,令perm(X)表示集合X的元素所组成的所有排列,令 er.perm(X)表示在perm(X)中的每
快速排序法—递归函数
weixin_45702470的博客
04-16 1822
基于递归快速排序快速排序排序思想概要:主要思想:代码 快速排序 即将一组有序数进行排序(由大到小) 排序思想 概要: 冒泡法是将第一个数作为标准与下面的数进行一一比较。快速排序时间复杂度较大。 快速排序是将一个数作为标准指派两个数进行比较(好处:这两个数若提示满足即可交换)。 主要思想: 设定两个判断交换数(与基准作比较),相当于两个哨兵(左哨兵、右哨兵)。 !!!接下来要做的就是把小于基准的放...
python快速递归方法_快速排序python(递归)
06-03
快速排序是一种常见的排序算法,也是使用递归实现的。以下是快速排序的python实现: ```python def quick_sort(arr): if len(arr) <= 1: return arr else: pivot = arr[0] left = [] right = [] for i in arr[1:]: if i < pivot: left.append(i) else: right.append(i) return quick_sort(left) + [pivot] + quick_sort(right) ``` 这个实现过程使用了一个关键的递归操作:将数组拆分成左右两个子数组,然后将它们分别进行快速排序,最后将它们合并起来。在每次递归调用中,我们都会将数组拆分成两个更小的子数组,这样我们就可以在较小的数组上进行排序,从而实现快速排序

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
写文章

热门文章

  • 【HTML】HTML学习笔记(全) 16439
  • PAT | 求给定精度的简单交错序列部分和 9877
  • 最大子列和问题(四种方法 !!!终极版本) 6059
  • 一元多项式的乘法与加法运算 5867
  • C语言文件详解(超级详细,记得收藏~~~) 4982

分类专栏

  • 【算法刷题】
  • 【Linux】 20篇
  • 【C++】 22篇
  • 【C语言】 17篇
  • 【前端】 5篇
  • CSS 4篇
  • HTML 1篇
  • 探索时期的博客 66篇
  • 【算法】 49篇
  • 【数据结构】 19篇
  • 【Python】 6篇
  • 开发工具 4篇

最新评论

  • 【数据结构】快速排序非递归实现

    柚凉OO: 满满的培训机构

  • 习题7-5 找鞍点 (20 分) | PAT【思路清晰】

    m0_64942353: 能过测试但是有问题,比如{2,2}{3,1}正确结果应该是0 0但这个程序给的是none,因为遇到=的情况直接用后面的列数替了,所以不会对前面的列进行验证

  • PAT | 求给定精度的简单交错序列部分和

    1998214: 等于1表情包

  • PAT | 求给定精度的简单交错序列部分和

    白开水喝五瓶: eps等于首项;eps超过首项这两种情况怎么处理?

  • 使用getline读取一整行

    CSDN-Ada助手: 多亏了你这篇博客, 解决了问题: https://ask.csdn.net/questions/8012447, 请多输出高质量博客, 帮助更多的人

您愿意向朋友推荐“博客详情页”吗?

  • 强烈不推荐
  • 不推荐
  • 一般般
  • 推荐
  • 强烈推荐
提交

最新文章

  • Linux下Gitee的user和email配置,查看配置信息命令
  • 【Linux】进程程序替换 &&简易mini_shell实现
  • 【Linux】实用小技巧,如何同时make多个可执行文件?
2023年1篇
2022年66篇
2021年152篇

目录

目录

评论 27
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JoyCheung-

赏颗糖吃吧~~~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或 充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值

深圳SEO优化公司揭阳网站优化排名公司南澳seo排名公司大丰高端网站设计推荐上海百姓网标王价格天水seo网站推广报价鄂州关键词排名价格德阳SEO按效果付费价格大庆外贸网站设计哪家好木棉湾英文网站建设哪家好广东网站优化按天收费价格三亚seo网站推广多少钱自贡网站制作设计公司潮州网站推广方案价格宜宾seo网站优化推荐福田SEO按天计费哪家好海北网站优化软件多少钱泸州网站推广方案价格来宾外贸网站制作哪家好张北网站推广桐城网站搭建报价中卫关键词排名包年推广哪家好阿坝网站开发价格崇左关键词按天收费哪家好吉林网站改版价格诸城百搜标王推荐坑梓推广网站陇南外贸网站制作公司安庆网站定制推荐莱芜网站推广工具哪家好文山关键词按天扣费多少钱歼20紧急升空逼退外机英媒称团队夜以继日筹划王妃复出草木蔓发 春山在望成都发生巨响 当地回应60岁老人炒菠菜未焯水致肾病恶化男子涉嫌走私被判11年却一天牢没坐劳斯莱斯右转逼停直行车网传落水者说“没让你救”系谣言广东通报13岁男孩性侵女童不予立案贵州小伙回应在美国卖三蹦子火了淀粉肠小王子日销售额涨超10倍有个姐真把千机伞做出来了近3万元金手镯仅含足金十克呼北高速交通事故已致14人死亡杨洋拄拐现身医院国产伟哥去年销售近13亿男子给前妻转账 现任妻子起诉要回新基金只募集到26元还是员工自购男孩疑遭霸凌 家长讨说法被踢出群充个话费竟沦为间接洗钱工具新的一天从800个哈欠开始单亲妈妈陷入热恋 14岁儿子报警#春分立蛋大挑战#中国投资客涌入日本东京买房两大学生合买彩票中奖一人不认账新加坡主帅:唯一目标击败中国队月嫂回应掌掴婴儿是在赶虫子19岁小伙救下5人后溺亡 多方发声清明节放假3天调休1天张家界的山上“长”满了韩国人?开封王婆为何火了主播靠辱骂母亲走红被批捕封号代拍被何赛飞拿着魔杖追着打阿根廷将发行1万与2万面值的纸币库克现身上海为江西彩礼“减负”的“试婚人”因自嘲式简历走红的教授更新简介殡仪馆花卉高于市场价3倍还重复用网友称在豆瓣酱里吃出老鼠头315晚会后胖东来又人满为患了网友建议重庆地铁不准乘客携带菜筐特朗普谈“凯特王妃P图照”罗斯否认插足凯特王妃婚姻青海通报栏杆断裂小学生跌落住进ICU恒大被罚41.75亿到底怎么缴湖南一县政协主席疑涉刑案被控制茶百道就改标签日期致歉王树国3次鞠躬告别西交大师生张立群任西安交通大学校长杨倩无缘巴黎奥运

深圳SEO优化公司 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化