数组中查找第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]);

}

查找数组序列中的第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
原创粉丝点击