c++ 快排思想查找第k小数……注意是小
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c++ 快排思想查找第k小数……注意是小相关的知识,希望对你有一定的参考价值。
RT
给定一个大小为n的数组s和一个整数K,请找出数组中的第K小元素。
这是一个补充程序的试题,你需要完成一个函数:
int findKth(int *s, int n, int K)
表示在s指向的数组中找到第K小的元素(如果K=1,表示找最小元素),你需要返回该元素的值。
一趟排序划分出基准位置pivot
1. pivot == k - 1,则pivot 位置数据就是
2. pivot > k - 1,则在左半继续寻找
3. pivot < k - 1,则在右半继续寻找
以下是程序:
int select(int s[ ], int left, int right, int k)
// 在s[ left .. right ]中选择第k 小的元素
if (left >= right)
return s[left];
int i = left; // 从左至右的标志
int j = right + 1; // 从右到左的标志
int pivot = s[left]; // 将最左面的元素作为分界数据
while (true)
do
// 在左侧寻找>= pivot 的元素
i = i + 1;
while (s[i] < pivot);
do
// 在右侧寻找<= pivot 的元素
j = j - 1;
while (s[j] > pivot);
if (i >= j) // 未发现交换对象
break;
int temp = s[i];
s[i] = s[j];
s[j] = temp;
if (j - left + 1 == k)
return pivot;
s[left] = s[j]; // 设置pivot
s[j] = pivot;
if (j - left + 1 < k) // 对一个段递归
return select(s, j + 1, right, k - j - 1 + left);
else
return select(s, left, j - 1, k);
int findKth(int *s, int n, int K)
// 返回 s[0 .. n - 1]中第K 小的元素
if (K < 1 || K > n)
throw "error";
return select(s, 0, n - 1, K);
参考技术A 程序已经完成了,你看看是不是你想要的结果
#include<stdio.h>
int findKth(int *s, int n, int k)
int number,i,j,tmp=0,min=s[0];
for(i=0;i<k;i++)
min=s[i];
for(j=i;j<n;j++)
if(s[j]<min)
min=s[j];
tmp=j;
number=s[tmp];
s[tmp]=s[i];
s[i]=number;
return min;
void main()
int s[]=1,4,2,8,6,7,15,9,n=sizeof(s)/sizeof(int),k=6;
printf("第 %d 小的元素是:%d\n",k,findKth(s,n,k));
参考技术B 利用快排的思想,利用函数Partition()分段。①若pivot左边的数个数小于K,则j--; //从右向左扫描, 查找第1个关键字小于pivot的记录R[j] if(i<j
vijos1788 第k大
可以用类似快排的快速查找算法,主要是一个分治的思想,时间复杂度为O(n)。
快排用一个中间值把序列分为两个部分,设左边部分为[l,j],右边部分为[i,r]。
(1)如果j<k,那么第k大必然是在[i,r]中,所以[l,j]的部分就不需要继续排序,递归查找[i,r]区间即可。
(2)如果k<i,那么第k大必然是在[l,j]中,所以[i,r]的部分就不需要继续排序,于是我们就递归查找[l,j]。
#include<cstdio> #include<cctype> #include<algorithm> using namespace std; inline int read(){ char c; while(c=getchar(),!isdigit(c)); int x=c-‘0‘; while(c=getchar(),isdigit(c)) x=x*10+c-‘0‘; return x; } int a[100001]; int find(int l,int r,int x){ int i=l,j=r,mid=a[l+r>>1]; while(i<=j){ while(i<r && a[i]>mid) i++; while(j>l && a[j]<mid) j--; if(i<=j) swap(a[i++],a[j--]); } if(j<x && x<i) return mid; if(x<=j) return find(l,j,x); if(x>=i) return find(i,r,x); } int main(){ int n=read(),k=read(); for(int i=1;i<=n;i+=1) a[i]=read(); printf("%d",find(1,n,k)); return 0; }
以上是关于c++ 快排思想查找第k小数……注意是小的主要内容,如果未能解决你的问题,请参考以下文章