1.求n个元素序列中第k大的元素。
代码为:(代码中既包括找第2大的数又有随机第k大的数)
import java.util.Scanner;
public class FZ {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
System.out.print("请输入数组中元素的个数:");
int m=scanner.nextInt();
int P[]=new int[m];
for(int i=0;i<m;i++)
{
P[i]=(int)(Math.random()*100);
}
System.out.print("随机给出的一组数据为:");
for(int i=0;i<m;i++)
{
System.out.print(P[i]+" ");
}
FZ fz=new FZ();
fz.Partition(P, 0,m-1);
System.out.println("排序后的顺序为:");
for(int i=0;i<m;i++)
{
System.out.print(P[i]+" ");
}
System.out.print("随机数组中第二大的数为:");
fz.find(P, 0, m-1, 2);
System.out.println();
System.out.print("输入k的值:");
int k=scanner.nextInt();
System.out.println();
System.out.print("第"+k+"大的数为:");
fz.find(P, 0, m-1, k);
}
int Partition(int A[],int low,int high)
{
int temp=A[low];
while(low<high){
while(low<high&&A[high]<=temp) --high;
A[low]=A[high];
while(low<high&&A[low]>=temp) ++low;
A[high]=A[low];
}
A[low]=temp;
return low;
}
int find(int s[],int i,int j,int k)
{
int n=Partition(s,i,s.length-1);
if(n==k-1)
{
System.out.print(s[n]);
}
else if(n<k){
find(s,n+1,s.length-1,k);
}
else
{
find(s,0,n-1,k);
}
return 0;
}
}
截图:
2.最近对问题(二维平面上的点),编程实现用分治法求解。
最近点对算法:
double cpair2(S)
{
n=|S|;
if (n < 2) return 0;
1)、m=S中各点x坐标的中位数;
//构造S1和S2;
S1={p∈S|x(p)<=m},
S2={p∈S|x(p)>m}
2)、d1=cpair2(S1);
d2=cpair2(S2);
3)、dm=min(d1,d2);
4)、设P1是S1中距垂直分割线l的距离在dm之内的所有点组成的集合;
P2是S2中距分割线l的距离在dm之内所有点组成的集合;
将P1和P2中点依其y坐标值排序;
并设X和Y是相应的已排好序的点列;
5)、通过扫描X以及对于X中每个点检查Y中与其距离在dm之内的所有点(最多6个)可以完成合并;
当X中的扫描指针逐次向上移动时,Y中的扫描指针可在宽为2dm的区间内移动;
设dl是按这种扫描方式找到的点对间的最小距离;
6)、d=min(dm,dl);
return d;
}
代码:
import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;
public class Fzzjd {
public static Object fz(Point a[],int l,int r)
{
if (r-l==1)
{
return Juli(a[l],a[r]);
}
if(r-l==2)
{
double d1=(double) Juli(a[l],a[l+1]);
double d2=(double)Juli(a[l],a[r]);
double d3=(double)Juli(a[l+1],a[r]);
d1=Math.min(d1, d2);
d2=Math.min(d2, d3);
return d2;
}
int k=(l+r)/2;
double d1=(double) fz(a,l,k);
double d2= (double) fz(a,k+1,r);
double d=Math.min((double) d1, (double) d2);
int le=l;
int ri=r;
while(a[l].getX()<(a[k].getX()-d) && le<r)
le++;
while(a[r].getX()>(a[k].getX()+d) && ri>=l)
ri--;
for(int i=0;i<=ri;i++)
{
for(int j=i+1;j<=ri;j++){
if(a[j].getY()-a[i].getY()<d)
{
double d3=(double)Juli(a[i],a[j]);
if(d3<d)
d=d3;
}
else
break;
}
}
return d;
}
public static Object Juli(Point p1,Point p2)
{
double t; t=(p1.getX()-p2.getX())*(p1.getX()-p2.getX())+(p1.getY()-p2.getY())*(p1.getY()-p2.getY());
return t=Math.sqrt(t);
}
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
Point p[]= new Point[10];
System.out.println("输入一组点的坐标数据:");
for(int i=0;i<10;i++)
{
int x=scanner.nextInt();
int y=scanner.nextInt();
p[i]=new Point(x,y);
System.out.println("("+p[i].getX()+","+p[i].getY()+")");
}
int MINx=100000000;
double MAXx=0.1111111;
for(int i=0;i<10;i++)
{
if(p[i].getX()<MINx)
MINx=p[i].getX();
if(p[i].getX()>MAXx)
MAXx=p[i].getX();
}
int MID=(int) ((MINx+MAXx)/2);
System.out.println(MID);
Arrays.sort(p,new Comparator<Point>(){
@Override
public int compare(Point s1,Point s2){
return(s1.getX()>s2.getX())? 1:(s1.getX()==s2.getX())? 0:-1;
}
});
System.out.print("按照x轴排完序的数组为:");
for(int i=0;i<p.length;i++)
{
System.out.print("("+p[i].getX()+","+p[i].getY()+")");
}
System.out.println("最近点对的最小距离为:"+fz(p,0,9));
}
}
截图: