luogu1177:快排模板:二分排序详解

题目连接:该题是luogu试炼场的2-3:T1


题目大意:
1 给n个数字,要求按从小到大的顺序排好,输出;


解题思路:
1 主要是掌握二分排序的基础原理:分治与函数的自我调用
2 请看下图及讲解:

1 当前 第x层 的比较:
1)每次的排序区域是[L,R],执行比较的游标x从L向右移动>>,游标y从R向左移动<<,当y<x的时候,当前层的比较结束
2)x想右移必须满足:a[x]<mid ,否则x停下等待;
3)y想左移必须满足:mid<a[y] ,否则y停下等待;
4)如果x和y都停下来等待,又没有满足y<x的时候,交换a[x]和a[y]的值,继续进行当前层的比较

2 对于 第(x+1)层 需用分治的思想
1)完成从左边界到右游标的比较:[L,y];直到 L等于y
2)完成从左游标到右边界的比较:[x,R];直到 x等于R

3 直到最后一层时候,所有的左边界和右游标重合,左游标和右边界重合,整个排序完成。


如果你真正能看懂以上的内容,是否就不需要上代码了呢?(奸笑.jpg)

善良的ls,还是会给代码的:

//luogu1177:快排模板题
//二分排序的思想理解 

#include<cstdio>

int a[100000010];
int n;

void px(int l,int r) //二分排序模板 
{
	int x=l,y=r,m=a[(l+r)/2];//m是当前中间值 
	
	while(x<=y)
	{
		while(a[x]<m) x++;//x是左区间的游标,向右移动>> 
		while(a[y]>m) y--;//y是右区间的游标,向左移动<< 
		
		if(x<=y)//如果不动了,交换当前值 
		{
			int t=a[x]; a[x]=a[y]; a[y]=t; x++; y--;
		}
	}
	//排好了当前的左右区间,进下一层的两个区间排更小的 
	if(l<y) px(l,y);
	if(x<r) px(x,r);
}

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

猜你喜欢

转载自blog.csdn.net/liusu201601/article/details/88567522