数组中查找第k小元素的复杂度为O(n)的算法
来源:互联网 发布:surface studio 知乎 编辑:程序博客网 时间:2024/05/17 06:59
import java.util.Random;
public class hello{
public static int []aa;
public static void main(String args[])
{
int []b=new int[11];
// int []b={8,4,7,8,6,5,10,8,6,10,8};
int l=0,k=5;
Random rand=new Random();
for(int i=0;i<b.length;++i){
b[i]=rand.nextInt(b.length);
System.out.println(b[i]);
}
aa=b;
// int result1=q_search_rec(l,aa.length-1,k-1); //数组下标和实际序号差1
// System.out.println("递归调用的:第"+k+"小的数是");
// System.out.println(aa[result1]);
int result2=q_search_ite_ditto(l,aa.length-1,k-1);
System.out.println("循环迭代的:第"+k+"小的数是");
System.out.println(aa[result2]);
static int q_search_rec(int l,int n,int k)
{
Random rand=new Random();
int t=rand.nextInt(n-l+1)+l;
swap(l,t);
int m,i;
m=l;
for(i=l+1;i<=n;++i)
{
if(aa[i]<aa[l])
{
swap(++m,i);
}
}
swap(l,m);
if(m==k)
return m;
else if(m<k)
return q_search_rec(m+1,n,k);
else
return q_search_rec(l,m-1,k);
}
public static void swap(int a,int b) //交换下标为a,b的元素
{
int c;
c=aa[a];
aa[a]=aa[b];
aa[b]=c;
}
int m,i,low =l,high=n;
Random rand =new Random();
while(low<=high){
int t=rand.nextInt(high-low+1)+low;
swap(low,t);
m=low;
for(i=low+1;i<=high;++i)
{
if(aa[i]<aa[low])
swap(++m,i);
}
swap(m,low);
if(m==k)
return m;
else if(m<k){
low=m+1;
// System.out.println("low值:"+low);
}
else{
high=m-1;
// System.out.println("high值:"+high);
}
}
return -1;
}
//有大量相同元素,改进算法效率的方案 即增加q,low~m的小于t,m~q的等于t,q~high的大于t
static int q_search_ite_ditto(int l,int n,int k){
int low,high,m,t,q,xx;
low=l;high=n;
Random rand=new Random();
while(low<=high)
{
t=rand.nextInt(high-low+1)+low;
swap(t,low);
m=low;q=low;
for(int i=low+1;i<=high;++i)
{
if(aa[i]<aa[low])
{
swap(++q,i);
swap(++m,q);
System.out.println("");
}
else if(aa[i]==aa[low])
{
swap(++q,i);
}
}
swap(low,m);
if(k>=m&&k<=q)
{
for(xx=m;xx<=q;xx++)
System.out.println("m~q之间的值:"+aa[xx]);
return m;
}
else if(m>k)
{
high=m-1;
// System.out.println("high值:"+high);
}
else
{
low=q+1;
// System.out.println("low值:"+low);
}
}
return -1;
}
}
public class hello{
public static int []aa;
public static void main(String args[])
{
int []b=new int[11];
// int []b={8,4,7,8,6,5,10,8,6,10,8};
int l=0,k=5;
Random rand=new Random();
for(int i=0;i<b.length;++i){
b[i]=rand.nextInt(b.length);
System.out.println(b[i]);
}
aa=b;
// int result1=q_search_rec(l,aa.length-1,k-1); //数组下标和实际序号差1
// System.out.println("递归调用的:第"+k+"小的数是");
// System.out.println(aa[result1]);
int result2=q_search_ite_ditto(l,aa.length-1,k-1);
System.out.println("循环迭代的:第"+k+"小的数是");
System.out.println(aa[result2]);
}
查找数组序列中的第k小元素的代码如下,框架类似于quick_sort(),区别是其只对包含第k小元素的那一侧进行运算,所以复杂度只有O(n)。
//递归快速查找方法static int q_search_rec(int l,int n,int k)
{
Random rand=new Random();
int t=rand.nextInt(n-l+1)+l;
swap(l,t);
int m,i;
m=l;
for(i=l+1;i<=n;++i)
{
if(aa[i]<aa[l])
{
swap(++m,i);
}
}
swap(l,m);
if(m==k)
return m;
else if(m<k)
return q_search_rec(m+1,n,k);
else
return q_search_rec(l,m-1,k);
}
public static void swap(int a,int b) //交换下标为a,b的元素
{
int c;
c=aa[a];
aa[a]=aa[b];
aa[b]=c;
}
//下面是迭代算法。注意迭代算法部分,while循环条件是low<=high,而不是“<”。原因是:当运行过程中low==k,而high=m=k+1时,此时运行到if条件句时,high=m-//1=low;函数会返回-1报错。
static int q_search_ite(int l,int n,int k){int m,i,low =l,high=n;
Random rand =new Random();
while(low<=high){
int t=rand.nextInt(high-low+1)+low;
swap(low,t);
m=low;
for(i=low+1;i<=high;++i)
{
if(aa[i]<aa[low])
swap(++m,i);
}
swap(m,low);
if(m==k)
return m;
else if(m<k){
low=m+1;
// System.out.println("low值:"+low);
}
else{
high=m-1;
// System.out.println("high值:"+high);
}
}
return -1;
}
//有大量相同元素,改进算法效率的方案 即增加q,low~m的小于t,m~q的等于t,q~high的大于t
static int q_search_ite_ditto(int l,int n,int k){
int low,high,m,t,q,xx;
low=l;high=n;
Random rand=new Random();
while(low<=high)
{
t=rand.nextInt(high-low+1)+low;
swap(t,low);
m=low;q=low;
for(int i=low+1;i<=high;++i)
{
if(aa[i]<aa[low])
{
swap(++q,i);
swap(++m,q);
System.out.println("");
}
else if(aa[i]==aa[low])
{
swap(++q,i);
}
}
swap(low,m);
if(k>=m&&k<=q)
{
for(xx=m;xx<=q;xx++)
System.out.println("m~q之间的值:"+aa[xx]);
return m;
}
else if(m>k)
{
high=m-1;
// System.out.println("high值:"+high);
}
else
{
low=q+1;
// System.out.println("low值:"+low);
}
}
return -1;
}
}
0 0
- 数组中查找第k小元素的复杂度为O(n)的算法
- 已知数组A[1...n] ,确定第K小元素 算法的时间复杂度O(n)
- 寻找数组中第k小的数:平均情况下时间复杂度为O(n)的快速选择算法
- 求数组第k小的元素 要求复杂度在O(n)
- 从俩个有序数组中找出第K小的数。要求时间复杂度O(logmin(m,n))
- 如何用O(n)时间复杂度查找第k大数的优化算法 C++程序
- 求第k小的数 O(n)复杂度
- 查找数组中第k小的元素
- 把一个含有N个元素的数组循环右移K位, 要求时间复杂度为O(N)
- 实现数组元素倒序的算法,写出两种实现,时间复杂度为O(n)和O(n/2)
- 找出大数组array中第k大的元素(要求时间复杂度O(1))
- 强大的随机算法-简洁的O(n)时间复杂度解决查找第k大数问题优化算法
- 在O(n)时间内查找数组内第k小的数
- O(n)查找第k小(大)的数
- 找出一个无环单链表里面的倒数第K个元素,时间复杂度为O(n)
- 时间复杂度为o(N)查找1至N-1构成的a[N]重复元素
- 时间复杂度为o(N)查找1至N-1构成的a[N]重复元素
- 时间复杂度为o(N)查找1至N-1构成的a[N]重复元素
- Spring security 3中登录后跳转到不同页面
- org.apache.hadoop.mapred.InvalidInputException: Input path does not exist问题
- Davinci :U-Boot简介
- 第八章 采用PCA(主成分分析)或LDA(线性判别分析)的人脸识别(一)
- 中缀式变后缀式(nyoj 467)
- 数组中查找第k小元素的复杂度为O(n)的算法
- 简单的 随机 生成不重复 数字的小程序
- 编程巨星的唯一秘诀
- Spring Security教程(大纲)----学习过程分享
- 序言
- Head First设计模式-简单工厂模式
- 第八章 采用PCA(主成分分析)或LDA(线性判别分析)的人脸识别(二)
- Spring Security教程(1)----SpringSecurity3.2环境搭建
- Java 自动装箱和拆箱