最近点对问题Word格式.doc
《最近点对问题Word格式.doc》由会员分享,可在线阅读,更多相关《最近点对问题Word格式.doc(8页珍藏版)》请在冰豆网上搜索。
找一条中垂线(坐位集合坐标的中位数)把个元素分成左右两部分元素,然后分别求得两边的最短距离,,然后取两者中的最小者记为,在中线两边分别取的距离,记录该距离范围内点的个数,中线左边有个元素,右边有个元素,分别将两边的点按y坐标升序排列,在左边集合中每一个点,找右边集合的点,找到与之距离小于的点,更新最短距离,直到循环结束,即可求出最短距离。
复杂度分析:
应用分治法求解含有个点的最近对问题,其时间复杂性可由递推式表示:
。
由以上分析:
合并子问题的解的时间。
进而可得分治法求最近对问题的时间复杂度为:
程序代码:
#include<
stdio.h>
stdlib.h>
math.h>
#defineNUM1000
typedefstruct{
intx;
inty;
}N;
doubledistance(Nn1,Nn2);
doubleminDis(doubled1,doubled2);
doubleshortestDis(N*data,intlength,N*n1,N*n2);
doubleshortestDis(N*data,intlength,N*n1,N*n2){
intpre,last,middle,median;
inti,c1num=0,c2num=0,j;
N*dataP;
N*dataL;
N*CP;
N*CL;
Ntn1,tn2;
doubledis1,dis2;
//当只有两个点时,返回最短距离,和点
if(length==2){
doubledis1=distance(data[0],data[1]);
*n1=data[0];
*n2=data[1];
returndis1;
}elseif(length==3){
//当只有三个点时,返回最短距离,和点
doubledis1=distance(data[0],data[1]);
doubledis2=distance(data[1],data[2]);
doubledis3=distance(data[0],data[2]);
doubletemp;
temp=dis1<
dis2?
dis1:
dis2;
temp=temp<
dis3?
temp:
dis3;
if(temp==dis1){
*n2=data[1];
}elseif(temp==dis2){
*n1=data[1];
*n2=data[2];
}else{
}
returntemp;
}
middle=length/2;
pre=middle;
last=length-pre;
median=data[middle].x;
//记录中位数
dataP=(N*)malloc(sizeof(N)*pre);
dataL=(N*)malloc(sizeof(N)*last);
CP=(N*)malloc(sizeof(N)*pre);
CL=(N*)malloc(sizeof(N)*last);
for(i=0;
i<
pre;
i++)
dataP[i]=data[i];
for(i=0;
i<
last;
dataL[i]=data[i+pre];
dis1=shortestDis(dataP,pre,n1,n2);
dis2=shortestDis(dataL,last,&
tn1,&
tn2);
if(dis1>
dis2){
*n1=tn1;
*n2=tn2;
dis1=minDis(dis1,dis2);
for(i=0;
i<
i++)
if(dataP[i].x-median<
dis1){
CP[c1num++]=dataP[i];
}//将在中位数之前的区域中与中位数距离小于最短距离的点放到CP中
last;
if(median-dataL[i].x<
CL[c2num++]=dataL[i];
}//将在中位数之后的区域中与中位数距离小于最短距离的点放到CL中
for(i=0;
c1num;
i++){
for(j=0;
j<
c2num;
j++){
doubletemp=distance(CP[i],CL[j]);
if(temp<
dis1=temp;
*n1=CP[i];
*n2=CL[j];
}
}
}//依次计算中位数两旁的区域中,每一个点与另外一个区域中的距离,并且记录最短距离
returndis1;
}
doubledistance(Nn1,Nn2){
returnsqrt((n1.x-n2.x)*(n1.x-n2.x)+(n1.y-n2.y)*(n1.y-n2.y));
doubleminDis(doubled1,doubled2){
doubled=d1<
d2?
d1:
d2;
returnd;
//分治法排序
voidMergeSort(Nq[],intnum,intmode){
inti,nump,numl;
N*qPre;
N*qLast;
if(num==1)
return;
if(num%2&
&
num!
=2){
numl=num/2;
nump=num/2;
nump++;
qPre=(N*)malloc(sizeof(N)*nump);
qLast=(N*)malloc(sizeof(N)*numl);
nump;
qPre[i]=q[i];
i<
numl;
qLast[i]=q[nump+i];
MergeSort(qPre,nump,mode);
MergeSort(qLast,numl,mode);
Merge(qPre,qLast,q,nump,numl,mode);
voidMerge(N*pre,N*last,N*total,intnump,intnuml,intmode){
inti=0,j=0,k=0;
while(i<
nump&
j<
numl){
if(mode==0){
if(pre[i].x>
last[j].x){
total[k++]=pre[i++];
}else{
total[k++]=last[j++];
}
}else{
if(pre[i].y>
last[j].y){
if(i==nump){
for(i=j;
numl;
total[k++]=last[i];
for(j=i;
j++)
total[k++]=pre[j];
voidcomputeShortestDistance(N*data,intnum,intresult[4]){
FILE*fo;
inti,j,l=0;
int*datax,*datay;
doubledis=666666,temp;
datax=(int*)malloc(sizeof(int)*1000);
datay=(int*)malloc(sizeof(int)*1000);
for(i=0;
num;
datax[i]=data[i].x;
datay[i]=data[i].y;
num;
for(j=i+1;
j<
j++)
if((temp=(datax[i]-datax[j])*(datax[i]-datax[j])+(datay[i]-datay[j])*(datay[i]-datay[j]))<
dis){