★问题描述
在快速排序过程中,每次会找一个划分值,将小于划分值的放到其左边,大于划分值的放右边,然后再依次递归左右两边,对子序列进行同样的操作,直到子序列为空则停止操作。最后就得到了有序的序列。
?如何找到一个合适的划分值?小茗同学也不知道,所以他用了随机算法。小茗同学的运气很好,每次都刚好随机到中位数,但是他也不知道这个过程中使用到的划分值都是多少。所以你需要帮助小茗同学找出整个排序过程中,用到的所有划分值,并按照其用到的顺序输出。
假定:
(1)快速排序优先递归排序左边序列,然后才是右边序列;
(2)中位数定义为序列中的第?n/2?大的数(n表示序列长度,??表示向上取整)。如3 4 1的中位数是3,3 4 1 2的中位数是2;
★数据输入
输入的第一行为数字n (1?≤?n?≤?10^5),表示给定序列的长度。 ?第二行包含n个整数,表示序列中的整数a1,?a2,?…,?an。(1?≤?ai?≤?10^9)。序列中的数互不相同。
★数据输出
在一行中依次输出划分值。
★输入示例
5
3 1 5 2 4
★输出示例
3 1 2 4 5
解题思路:
这就是在考察你到底有没有弄清楚快速排序的过程吧…
代码实现反倒对这问题来说是其次了
题目描述本身就有问题, 3 4 1 2的中位数按他的说法应该取第2大的数,也就是3,可实际却取了2
快排过程中每趟所选用的划分值刚好是中位数,那我们要找每次递归过程所处理的区间的中位数的话,就要对这个区间进行排序。
反正快排的过程就是把递归划分出来的所有区间都有序化以后再把它们"拼凑"成整个有序区间,索性直接就先把整个序列都有序化,然后再在它中模拟快排划分左右区间的过程,再去左右区间里找中位数就行了。
//Matsuri
#include<iostream>
#include<cstdio>
#include<algorithm>
#define MAX 200001
using namespace std;
int n,a[MAX];
// 排序+二分查找
void BinarySearch(int t[],int l,int r)
{
if (l<=r)
{
int mid=(l+r)>>1;
printf("%d ",t[mid]);
BinarySearch(a,l,mid-1);
BinarySearch(a,mid+1,r);
}
}
int main()
{
scanf("%d",&n);
for (int i=0;i<n;i++) scanf("%d",&a[i]);
sort(a,a+n);
BinarySearch(a,0,n-1);
return 0;
}