快速排 序

前言

快速排序应该是我目前遇到的排序中比较难懂的一个,在这里我将详细展示自己的理解过程,希望能够帮助到大家,至少能做个参考吧

快排原理

这里我给出一组数{7,9,3,2,4,8},我们任意选择一个数作为关键数,这里我们就都以最左边的数作为关键数,即“7”。接下来我们就要判断后面的数和7的大小关系,小于7的分为1组,大于7的另成1组,即{7,3,2,4,8,9}。(这里只是介绍原理,实际的排序以程序运行为准)然后我们再把7放到中间,(这里只需要把7和4交换)即{4,3,2,7,8,9},然后这堆数就分成了两组我
们现在只需要对这两组数重复上面的方法即可,直到每一组只剩下1个数。这里我简单记录一下排序过程
在这里插入图片描述
如果想要更深入理解快排的话可以看看这个视频冒泡排序,插入排序,快速排序的对比

程序实现

这里我只介绍一下排序的函数

void sort(int a[],int left,int right){
int l=left,r=right,key=a[l],temp;//key代表关键值,我们始终选择相对左值为关键值,temp作为媒介值使用,用于交换数据。

注意,这里的left表示绝对的“左”,其值始终为0;而l表示相对的“左”,其值会变化。right和r一样。

接下来是分组,即小于key的值为一组,大于key为另一组

while(l<r){//l的初始值为left,r为right,分别对应左右两边两个数
		while(l<r&&a[r]>key)r--;//从最右边开始判断,若此值大于key值则r-1,判断前面一个值,直到a[r]<=key。
		while(l<r&&a[l]<=key)l++;//因为key值在最左边,所以判断第一个数时肯定是相等的即a[l]=key所以要加=
		temp=a[l],a[l]=a[r],a[r]=temp;//交换值!

		}

这段代码可能会比较难懂,这里我给出它的图解
在这里插入图片描述
交换过后程序会循环,直到l和r重合,然后我们就可以把key值与lr重合位置的值交换,这样key值就到中间去了,数据被分成了两组,一大一小

temp=a[left],a[left]=a[l],a[l]=temp;

最后,只需要把分成的两组数据重复上述操作,直到每组只剩1个数据即可

if(left<l-1)sort(a,left,l-1);//如果该组只有一个数据,if就不成立
if(right>r+1)sort(a,r+1,right);

在这里插入图片描述

所有代码如下

void sort(int a[],int left,int right){//left表示绝对左值,l表示相对左值 
	int l=left,r=right,key=a[l],temp;//选择关键值 ,定义媒介值 
	while(l<r){
		while(l<r&&a[r]>key)r--;
		while(l<r&&a[l]<=key)l++;
		temp=a[l],a[l]=a[r],a[r]=temp;
		}
		temp=a[left],a[left]=a[l],a[l]=temp;
		if(left<l-1)sort(a,left,l-1);
		if(right>r+1)sort(a,r+1,right);
	}

总结

以上就是所有内容,对于一些比较复杂难懂的程序可以将其写到纸上分析,按照程序一步一步地进行,这对程序的理解很有帮助。

快速的基本思路是:选取一个基准元素,将列中比它小的元素放在它的左边,比它大的元素放在它的右边,然后对左右两边分别进行递归。第一趟快速的过程如下: 1.选取基准元素:选择列中的第一个元素 Tim 作为基准元素。 2.进行划分:从列的第二个元素开始,依次将每个元素与基准元素进行比较。将比基准元素小的元素放在基准元素左边,大于等于基准元素的元素放在基准元素右边。 初始状态: (Tim,Kay,Eva,Roy,Dot,Jon,Kim,Ann,Tom,Jim,Guy,Amy) 第一次划分后: (Tim,Kay,Eva,Amy,Dot,Jon,Kim,Ann,Tom,Jim,Guy,Roy) 3.确定基准元素位置:此时基准元素 Tim 已经被放置在了列中的正确位置,它的左边都是比它小的元素,右边都是大于等于它的元素。我们可以将列分成两个部分,分别对左右两个部分进行递归。 左半部分:(Eva,Amy,Dot,Jon,Kay,Kim,Ann,Tom,Jim,Guy) 右半部分:(Roy) 注意:在这个过程中,基准元素的位置不发生改变,因此它不需要参与左右子列的。 4.递归:对左右两个部分分别进行递归,直到所有子列都有。 左半部分的过程: 选取基准元素:选择列中的第一个元素 Eva 作为基准元素。 进行划分:从列的第二个元素开始,依次将每个元素与基准元素进行比较。将比基准元素小的元素放在基准元素左边,大于等于基准元素的元素放在基准元素右边。 第一次划分后: (Eva,Amy,Dot,Jon,Kay,Kim,Ann,Tom,Jim,Guy) 左半部分已经有,无需递归。 右半部分的过程: 选取基准元素:选择列中的第一个元素 Roy 作为基准元素。 进行划分:从列的第二个元素开始,依次将每个元素与基准元素进行比较。将比基准元素小的元素放在基准元素左边,大于等于基准元素的元素放在基准元素右边。 第一次划分后: (Roy) 右半部分已经有,无需递归。 最终结果为: (Amy,Ann,Dot,Eva,Guy,Jim,Jon,Kay,Kim,Roy,Tim,Tom)
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值