算法 - 快速排序(Quick_sort)

这篇具有很好参考价值的文章主要介绍了算法 - 快速排序(Quick_sort)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

什么是快速排序?

快速排序的使用场景:

演示快速排序的过程:

第一趟排序:

第二趟排序:

通过代码来实现:

 对快速排序的总结:


什么是快速排序?

在写快速排序的代码之前,我们先对快速排序的排序原理以及定义进行梳理:

快速排序(Quick_sort)是对冒泡排序的一种改进,它也是属于冒泡类的方法。它的基本思想是通过一趟排序将待排序列分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,然后对这两部分的分割后的序列再次进行排序,直到达到整个序列有序的目的。

快速排序相当于是冒泡排序升级版本,排序特点就是越乱越快,所以也是一种高效的算法。快速排序就是一个给基准数据并找到其正确索引位置的过程。

快速排序的使用场景:

对于数据量大,数据分布高度随机的场景,使用快速排序算法的效率是非常高的,甚至高于堆排序。

演示快速排序的过程:

我在这里给出来一个随机数组:

int ar[11] = {12,21,6,3,23,2,3,2,1,14,3};

我们用一个总图来描绘快速排序的过程:

 算法 - 快速排序(Quick_sort)

在这里我重新给出一个数组我们分步来分析:

int ar[10] = {4,7,9,6,5,3,10,2,8,1};

第一趟排序:

接下来我们在画板上演示快速排序的过程:

算法 - 快速排序(Quick_sort)

在这里我们首先选定基准元素,基准元素的选择是随机的,我们为了方便起见直接选择序列的第一个元素4作为基准元素,然后我们定义两个指针变量分别指向序列的开始和序列的末尾。我们把基准元素拿出来,此时第一个元素的位置就相当于是一个坑。 

我们从右边的指针开始,把指针指向的元素和基准元素做比较,如果指针所指向的元素比基准元素大则把指针向左移动,如果指针所指向的元素是小于基准元素的我们则把指针所指向的元素填入坑中。我们发现此时的1是小于4的,则把1填入至坑中。

算法 - 快速排序(Quick_sort)

这时1原本的位置成为了新的坑,同时p指针向后移动一位,此时我们发现p所指向的元素7是大于基准元素4的,于是我们把7填入坑的位置。

算法 - 快速排序(Quick_sort)

此时7原本的位置又成为了新的坑,我们现在将q指针向左移动,碰到了元素8大于基准元素,不动,直到碰到比基准元素小的数停下,此时q停到了2的位置,2  < 4我们这时将2填入坑的位置。

算法 - 快速排序(Quick_sort)

此时2原本的位置成为了新的坑,p指针向右移动,我们碰到了元素9,元素9是大于基准元素的,此时将元素9填入到坑的位置。

算法 - 快速排序(Quick_sort)

继续上述操作,原本9的位置变为了新的坑,q指针继续向左移动,我们发现当q指向元素3的时候,3小于基准元素,于是将3填入坑的位置。

算法 - 快速排序(Quick_sort)

原本3的位置变为了新坑,p指针向后移动我们发现元素6大于基准元素,于是将6填入坑中。

算法 - 快速排序(Quick_sort)

此时原本6的位置变为了新坑,q指针继续向左移动,移动一位发现元素5是大于基准元素的,所以5元素不动,继续向左移动,此时p指针和q指针相撞,这时我们将基准元素填回现在的坑中,此时第一趟排序完成。

算法 - 快速排序(Quick_sort)

我们更改元素的颜色,此时原基准元素4 左侧的蓝色方框的元素代表小于基准元素的区域,右侧黄色方格的元素代表大于基准元素的区域,

第二趟排序:

现在相当于我们在基准元素的两侧又重新分为了两列,左边的都小于基准元素,右边的都大于基准元素。然后这两列数列使用刚才的方法进行第二趟排序,这也是分治法的思想。

此时我们先对4左侧的元素进行快速排序:

算法 - 快速排序(Quick_sort)

此时我们将2元素拿出来当作基准元素,从右侧q指针所指向的元素进行比较,我们发现3大于1,继续将q指针向左侧移动,我们发现2大于1,q向左移动与p指针对撞,排序结束,将基准元素放回坑的位置。继续将2作为基准元素,从右侧指针q开始比较,我们发现3大于2,位置不动,q指针向左侧移动与p指针相撞排序结束。

现在我们对4右侧的元素进行快速排序:

算法 - 快速排序(Quick_sort)

此时我们将5元素拿出来当作基准元素,5的位置为坑,q指针指向的元素开始和基准元素做比较,q指针每一次向左移动所指向的元素均是大于5的,位置不动,直到q指针和p指针相撞,排序结束。算法 - 快速排序(Quick_sort)

第二趟我们用6作为基准元素,q现在向左边移动我们发现q每一次的移动所指向的元素均是大于6的,所以他们的位置不动。p指针所指向的5元素是小于6元素的,位置不动,现在重新将6元素置于坑中。

算法 - 快速排序(Quick_sort)

左子序列现在的长度仅为1,所以无需再做比较。此时我们将元素10作为基准元素拿出来,10原来的位置为坑,从右侧q指针所指向的元素7开始比较,我们发现7是小于10元素的,所以我们将7填入坑中(原来10的位置)。现在移动左侧p指针,p指针向后移动的每一个元素都是小于基准元素的,我们将10元素填入坑中,此时序列为:

算法 - 快速排序(Quick_sort)

指针对撞,第三趟排序结束。现在我们开始第四趟排序,将9作为基准元素拿出来,p指针指向9所在的位置:

算法 - 快速排序(Quick_sort)

现在从右侧q指针开始比较,10是大于9的位置不动,q向左迁移一位,8是小于9的,我们将8填入坑中,此时指针p向后迁移一位与指针q对撞,将9置于新的坑中,第四趟排序结束。

算法 - 快速排序(Quick_sort)

我们现在进行第五趟排序,右自序列的长度为 1,已经不需要再比较,排序完成。 

通过代码来实现:

#include<stdio.h>
#include<iostream>
#include<stdlib.h>
#include<assert.h>
#include<time.h>
#define MAXSIZE 11
void initar(int *ar,int len)
{
	assert(ar != nullptr);
	for(int i = 0;i < len;i++){
		ar[i] = rand() % 30;
	}
}
void showar(int *ar,int len)
{
	assert(ar != nullptr);
	for(int i = 0;i < len;i++){
		printf("%d ",ar[i]);
	}
	printf("\n--------------------------\n");
}
void Quick_sort(int *ar,int left,int right)
{
	assert(ar != nullptr);
	if(left >= right){
		return;
	}
	int i = left;//使用i下标代表左边界
	int j = right;//使用j下标代表右边界
	int pivot = ar[i];//pivot代表的就是基准元素,将i下标对应的元素取出当作基准元素
	while(i < j){//循环条件为左边界小于右边界
		while(i < j && ar[j] >= pivot)//循环条件为当右侧j下标对应的元素大于基准元素时
		j--;//j下标向左迁移一位
		ar[i] = ar[j];//将j下标对应的值挪到坑的位置,这里可以理解为将值赋给i下标对应的元素位置,也就是大的往前挪
		while(i < j && ar[i] <= pivot)//循环条件为当右侧下标j对应的值小于基准元素时
		i++;//i下标向右侧迁移一位
		ar[j] = ar[i];//就是把小值往后挪,进行赋值操作
	}
	ar[i] = pivot;//基准元素更新
	Quick_sort(ar,left,i - 1);//递归,基准元素的左半部分
	Quick_sort(ar,i + 1,right);//递归,基准元素的右半部分
}
int main()
{
    srand((unsigned int)time(NULL));
	int ar[MAXSIZE];
	initar(ar,MAXSIZE);
	printf("原始数据为:\n");
	showar(ar,MAXSIZE);
    printf("\n经过快速排序后的数据为:\n");
	Quick_sort(ar,0,MAXSIZE - 1);
	showar(ar,MAXSIZE);
    return 0;
}

运行结果:

算法 - 快速排序(Quick_sort)

排序完成 

 对快速排序的总结:

快速排序(Quick_sort)的特点就是:序列越乱越快,越有序越慢。

时间复杂度:

最优情况:O(nlogn)每趟排序数据元素都能被平均分配成两个部分,形成一个完美的二叉树。

最坏情况:O()也就是原序列相对最有序的情况,形成的树只有左子树和右子树,比较次数为:(n - 1) + (n - 2) + (n - 3)+……+ 1 = n * (n - 1)/2

空间复杂度:

O(1)

和希尔排序类似,序列元素的比较与交换是跳跃进行的,会改变元素的相对位置,所以快速排序依旧是一个不稳定算法,但这也不妨碍它是所有排序算法中平均效率最高的算法。文章来源地址https://www.toymoban.com/news/detail-495940.html

到了这里,关于算法 - 快速排序(Quick_sort)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【C++STL】快速排序算法(sort)的原理与使用

    一、 sort 算法原理 std::sort 是 C++ 标准库中提供的排序算法,它使用的是一种经典的排序算法—— 快速排序 (Quicksort)或者是其变种。 快速排序是一种基于比较的排序算法,通过不断地选择一个基准值(pivot),将待排序序列分割为两个子序列,其中一个子序列的所有元素小

    2024年02月09日
    浏览(46)
  • ⌈算法进阶⌋图论::拓扑排序(Topological Sorting)——快速理解到熟练运用

    目录  一、原理 1. 引例:207.课程表  2. 应用场景 3. 代码思路 二、代码模板 三、练习 1、210.课程表Ⅱ🟢 2、2392.给定条件下构造举证🟡 3、310.最小高度树🟡 4、 2603.收集树中金币 🔴 1. 引例:207.课程表 就如大学课程安排一样,如果要学习数据结构与算法、机器学习这类课程

    2024年02月11日
    浏览(48)
  • 排序算法(stable_sort(), sort())

    sort函数我相信大家都不陌生,今天介绍一个新的排序算法stable_sort stable_sort:稳定排序算法,维持相等元素的原有顺序。 假如我们定义一个字符串数组 这些字符串是按照字典序排列的,我们现在想要words按照单词长度从小到大重排的同时,还希望具有相同长度的元素按照字典

    2024年02月07日
    浏览(54)
  • 【排序算法】堆排序(Heap Sort)

    堆排序是指利用堆这种数据结构所设计的一种排序算法。堆是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。 学习堆排序之前,有必要了解堆!若读者不熟悉堆,建议先了解堆(建议可以通过二叉堆,左倾堆,

    2024年02月01日
    浏览(70)
  • 46,排序算法sort

    排序算法sort 常用排序算法 sort 学习目标: 掌握i常用排序算法 算法简介: sort //对容器内元素进行排序 random_shuffle //洗牌,指定范围内的元素随机调整次序 merge //容器元素合并,并存储到另一容器中 reverse //反转指定范围的元素 功能描述: 对容器内元素进行排序 函数原型:

    2024年02月16日
    浏览(41)
  • 【算法】桶排序(Bucket Sort)详解

    桶排序(Bucket Sort)又称箱排序,是一种比较常用的排序算法。其算法原理是将数组分到有限数量的桶里,再对每个桶分别排好序(可以是递归使用桶排序,也可以是使用其他排序算法将每个桶分别排好序),最后一次将每个桶中排好序的数输出。 桶排序的思想就是把待排序

    2024年01月24日
    浏览(43)
  • C++(15): STL算法:排序(sort)

            std::sort 是 C++ 标准库 algorithm 中提供的一个函数,用于对容器(如数组、向量等)中的元素进行排序。它基于比较操作对元素进行排序,通常使用高效的排序算法,如快速排序、归并排序或堆排序等。         在实际应用中,std::sort 通常会根据输入数据的大

    2024年04月12日
    浏览(35)
  • 算法 - 归并排序(Merge_sort)

    目录 什么是归并排序(Merging_sort)? 归并排序的适用场景: 演示归并排序的过程(默认arr和brr两个数组都是有序的): 代码实现: 如果我们事先并没有分配好两个已经排序好的数组,而是直接的一个无序序列呢? 代码实现: 在写归并排序的代码之前,我们先对归并排序的定义

    2024年02月13日
    浏览(49)
  • Sorting Algorithms in Python (排序算法)

    本篇文章主要介绍几种经典排序算法:冒泡排序、快速排序、选择排序、堆排序、插入排序、希尔排序、归并排序、桶排序和基数排序。并给出用python实现的算法代码。 目录 一、冒泡排序 二、快速排序 三、选择排序 四、堆排序 五、插入排序 六、希尔排序 七、归并排序 八

    2024年04月15日
    浏览(42)
  • 十大排序算法(Top 10 Sorting Algorithms)

    十种常见排序算法可以分为两大类: 比较类排序 :通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此也称为非线性时间比较类排序。 非比较类排序 :不通过比较来决定元素间的相对次序,它可以突破基于比较排序的时间下界,以线性时间运行,因

    2024年02月08日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包