快速排序(QUI)

快速排序是排序问题中较快的一种方法了,快速排序是另一个分而治之的排序算法,

建立快速排序也仅仅需要三步走

1>确定分界点 

起始点q[l]  结束点q[r]  中间索引q[(l+r)/2]建议这样也可以为随机值

2>调整范围

将索引看做为x ,将小于x的看分为一部分,将大于x分为一部分

3>递归处理左右两段

具体流程方法如下:

初始化各种开始值

int main()
{
	scanf("%d", &n);
	for (int i = 0; i < n; i++)scanf("%d", &q[i]);
	quick_sort(q, 0, n - 1);
	for (int i = 0; i < n; i++)printf("%d ", q[i]);
	return 0;
}

输入 n (接下来要排序的数字的个数)

输入数字,快排,输出数字

void quick_sort(int q[],int l,int r)

快排函数,引入数组q[],初始值 l ,结尾值r。

考虑特殊情况,当只有一个值时

应该直接返回即

if (l == r)return;

接着进行快排的真正算法

左索引设为 i , i要从0开始 ,右索引 设为  j ,j是元素个数-1(数组从0开始),x为数组中中间位的数值(不用区分奇偶,大差不差就行),比如

在此例中 i = 0 ,q[i]=3,r = 5,q[r]=5, x = q[(i+r)/2] = 2 ;

代码

int i = l; int j = r;int x = q[(l + r) / 2];

此时 q[i]=3 > x 索引不动 , q[j]=5 > x 为达到交换目的,索引持续左移接着就是 q[j] = 6 >x,继续……直到 q[j] = 2

while (q[i]<x)i++;
while (q[j]>x)j--;

;触发交换条件 当 i  <  j 时 交换 ;并且将i  j 分别两边移动

if (i <= j)
			{
				swap(q[i], q[j]);
				i++; j--;
			}

双索引指向同一个元素是也要进入循环否则就无法进行下一步,因此大循环判断为  i<=j

while (i <= j)

OK,目前就将数组分为两份了 j左边 和 i右边,在递归分别处理一下左右两边数组(递归不要忘记判断条件)。

if(l<j) quick_sort(q, l, j);
if(i<r) quick_sort(q, i, r);

 这样就结束了,如果想看一下代码的运行图形化可以参考

排序(冒泡排序,选择排序,插入排序,归并排序,快速排序,计数排序,基数排序) - VisuAlgo排序算法将一串数组(一个列表)中的元素(整数,数字,字符串等)按某种顺序(增大,减小,字典顺序等)重新排列。有很多种不同的排序算法,每一种都有各自的优势和限制。排序常常作为计算机课程中的介绍性问题,用以介绍一系列的算法思路。不失普遍性,我们在此可视化中,只将(可能包含重复)的整数数组排序至非减。试试点击 Bubble Sort 来可视化五个(含重复项)的杂乱整数的排序。icon-default.png?t=N7T8https://visualgo.net/zh/sorting

整体模版是


#include<iostream>

using namespace std;
const int N = 1e6 + 10;

int n;
int q[N];
void quick_sort(int q[],int l,int r)
{
	if (l == r)return;
	int i = l; int j = r;
	int x = q[(l + r) / 2];
	while (i <= j)
	{
		while (q[i]<x)i++;
	    while (q[j]>x)j--;
			if (i <= j)
			{
				swap(q[i], q[j]);
				i++; j--;
			}

	}
	if(l<j) quick_sort(q, l, j);
	if(i<r) quick_sort(q, i, r);
}

int main()
{
	scanf("%d", &n);
	for (int i = 0; i < n; i++)scanf("%d", &q[i]);
	quick_sort(q, 0, n - 1);
	for (int i = 0; i < n; i++)printf("%d ", q[i]);
	return 0;
}

 建议背过

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值