快速排序 详解 (C++实现)

学习视频:acwing算法基础课

目录

快排基本流程

 快排代码


快排基本思想:分治

快排基本流程

数组l到r:

1.确定一个分界点:q[l] 或 q[r] 或 q[(l+r)/2] 或 数组中随机一个数 把区间分为两半        假设取的值为x(x为数组中的数 而非数组下标)

 2.调整区间:使得x左边区间的数小于等于x,x右边区间的数大于等于x

        实现方法一:1)开两个数组a[ ],b[ ]

                              2)扫描数组q[ ]从下标 l 到下标 r 的部分,如果q[i]小于等于x就插入到a[ ],如果q[i]大于x就插入到b[ ]

                               3)先把a[ ]中的数放到q里,再把b[ ]中的数放在q里

        实现方法二:1)创建指针i,j(因为i,j要指的是数组中的元素 所以i,j直接用int即可),i指向l,j指向r

                                2)如果i指向的数(q[ i ])小于x,则q[ i ]应该在x左边,q[ i ]无需移动,i向右移动一位(i++);如果q[ i ]大于等于x,则q[ i ]应该在x的右边,i停止移动。再看j,如果j指向的数(q[ j ])大于x,则q[ j ]应该在x左右边,q[ j ]无需移动,j向左移动一位(j--);如果q[ j ]小于等于x,则q[ j ]应该在x的左边,j停止移动。

                                 3)交换i指向的数和j指向的数

                                 4)重复第2步直到i,j相遇

 i指向2,j指向8,这里x=4(x可以取数组中的任意一数)

i指向2时,2小于4,应该在4左侧,2无需移动,所以i右移一位指向5;5大于4,应在4右侧,所以i停止移动;为交换位置做准备

j指向8时,8大于4,应在4右侧,8无需移动,所以j左移一位指向3;3小于4,应在4左侧,所以j停止移动;为交换位置做准备

 交换3,5位置

 i,j指针本来指向的3,5是处理之后的结果,所以i,j各向中间移动一位

 i指向4,不小于4,所以i指针停止移动,看j指针,j指向5,大于4,所以5无需移动,j指针左移一位;i,j相遇   指针移动结束。此时4左侧均小于等于4,4右侧均大于等于4。

3.递归处理左右两段:递归处理左右两个区间(只要左右两个区间都排好序了整个区间就排好序了)

 快排代码

#include<iostream>
using namespace std;

const int N = 100005;//数组最大存储数量
int q[N], n;//q为数组,n为数组实际数量

//快排
void quick_sort(int l, int r)
{
	if (l >= r)return;//当l>+r时 返回
	
	int i = l - 1,j=r+1,x=q[l+r>>1];//取x值,以i为例,i++后比较q[i]与x的大小,为了使数组第一个值也能顺利比较,i=l--,这样进入循环后先i++,就可以让i=l,从l开始比较了
	
	//调整x左右两侧区间
	while (i < j)
	{
		do i++; while (q[i] < x);//如果q[i]<x,i右移;如果q[i]>=x则while条件不符合,跳出while循环
		do j--; while (q[j] > x);//如果q[j]>x,j左移;如果q[j]<=x则while条件不符合,跳出while循环

        //如果i,j跳出循环时i<j,交换q[i],q[j]的值
		if (i < j)
		{
			swap(q[i], q[j]);
		}
	}

	quick_sort(l, j);//调整l到j区间的值
	quick_sort(j + 1, r);//调整j+1到r区间的值
}

int main()
{
	cin >> n;
	for (int i = 0; i < n; i++)
	{
		scanf("%d",&q[i]);//读入数据较多时建议用scanf
	}
	
	quick_sort(0, n - 1);//调用快排函数
	
	for (int i = 0; i < n; i++)
	{
		cout << q[i]<<" ";
	}

	return 0;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值