社区讨论

快排六问

学术版参与者 2已保存回复 1

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
1 条
当前快照
1 份
快照标识符
@loblj4oc
此快照首次捕获于
2023/10/29 22:58
2 年前
此快照最后确认于
2023/11/04 03:52
2 年前
查看原帖
对于下面的代码:
第k小数:
CPP
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<string>
#include<queue>
#include<stack>
#include<queue>
#include<iomanip>

using namespace std;
int n,k,ans;
int a[5000010];
long long read(){
	long long x=0,h=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')h=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
	return x*h;
}

void q_sort(int l,int r){
	if(l==r){
		ans=a[l];
		return ;
	}
	int mid=a[(l+r)>>1];
	int i=l,j=r;
	do {
		while(a[i]<mid&&i<=j)i++;
		while(a[j]>mid&&i<=j)j--;
		if(i<=j){
			swap(a[i],a[j]);
			i++,j--;
		}
	}while(i<=j);
	if(k==j+1){
		ans=a[j+1];
		return ;
	}
	else if(k<=j){
		q_sort(l,j);
	}
	else {
		q_sort(i,r);
	}
}

int main(){
//	freopen("","r",stdin);
//	freopen("","w",stdout);
	n=read();k=read()+1;
	for(int i=1;i<=n;i++)a[i]=read();
	
	q_sort(1,n);
	cout<<ans<<endl;
	return 0;
}

快排模板:
CPP
void q_sort(int l,int r){
	if(l>=r)return ;
	int mid=a[(l+r)>>1];
	int i=l,j=r;
	do {
		while(a[i]<mid&&i<=j)i++;
		while(a[j]>mid&&i<=j)j--;
		if(i<=j){
			swap(a[i],a[j]);
			i++;j--;
		}
	}while(i<j);
	if(i<r)q_sort(i,r);
	if(j>l)q_sort(l,j);
	return ;
}
1.为什么是a[i]<mida[j]>mid而不是a[i]<=mida[j]>=mid
2.交换数的时候为什么i<=j,而不是i<j
3.为什么交换之后需要i++;j--;?如果不加此语句,并使用a[i]<=mida[j]>=mid,那么循环再进行一次然后就会退出,这样为什么不行?
4.如何解决while结束之后i,j的大小问题,因为i,j要与k比较,用i还是用j?i有可能等于j,有可能等于j+1,有可能等于j+2。
5.为什么k进行比较时,是与j+1比较,而不是j?
6.为什么快排决定选择使用哪段区间时,是i,r比较、j,l比较,而不是i,l比较、j,r比较?

回复

1 条回复,欢迎继续交流。

正在加载回复...