课程实验报告课程名称:算法设计与分析专业班级:信息安全1303学号:U**********名:***指导教师:***报告日期:2015-6-16计算机科学与技术学院目录目录 (2)实验一最近点对问题 (1)1.1实验内容与要求 (1)1.2算法设计 (1)1.3 实验结果与分析 (2)1.4编程技术与方法 (3)1.5 源程序及注释 (3)实验二大整数乘法 (8)2.1实验内容与要求 (8)2.2算法设计 (9)2.3 实验结果与分析 (12)2.4编程技术与方法 (12)2.5 源程序及注释 (12)实验三单源点 (14)3.1实验内容与要求 (14)3.2算法设计 (14)3.3 实验结果与分析 (14)3.4编程技术与方法 (16)3.5 源程序及注释 (16)实验四最优二分检索树 (19)4.1实验内容与要求 (19)4.2算法设计 (19)4.3实验结果与分析 (20)4.4源程序及注释 (22)五、实验心得与体会 (25)六、参考书目 (27)实验一最近点对问题1.1实验内容与要求已知平面上分布着点集P中的n个点p1,p2,...p n,点i的坐标记为(x i,y i),1≤i≤n。
两点之间的距离取其欧式距离,记为22)()(),(jijijiyyxxppd-+-=问题:找出一对距离最近的点。
注:允许两个点位于同一个位置,此时两点之间的距离为0要求:用分治法实现最近点对的问题。
1.2算法设计(1)首先将所有的点按照x坐标排序。
排序过程需要O(nlogn)的时间,不会从整体上增加时间复杂度的数量级。
(2)划分:由于点已经按x坐标排序,所以空间上可以“想象”画一条垂线,作为分割线,将平面上的点集分成左、右两半P L和P R。
如下图所示:分割线PL记, d L:P L中的最近点对距离;d R:P R中的最近点对距离;d C:跨越分割线的最近点对距离。
则,最近的一对点或者在P L中,或者在P R中,或者一个在P L中而另一个在P R中(跨越分割线)。
设点按它们的y坐标排序,如果p i和某个p j的y坐标相差大于δ,那么这样的p i可以终止计算,继续处理p i+1。
算法描述如下:for i=1 to numPointsInStrip dofor j=i+1 to numPointsInStrip doif p i and p j's y-coordinates differ by more than δbreak;else if dist(p i,p j)<δδ = dist(p i,p j);1.3 实验结果与分析实验数据:(1)点对数目:6(2)点对坐标:(1,3)(2,5)(3,12)(5,8)(6,9)(7,15)运行结果:如图显示的是最近点对<5.00,8.00><6.00,9.00>的距离为1.411.4编程技术与方法纵观整个过程,首先要对X坐标排序时间为O(NlogN),这是分治之前的预处理。
然后问题分成了N/2规模,然后用Q(N)的复杂度得到中间的最近点对,然后可以在常数时间内得到最终的点对与最近值。
So。
T(N)=2T(N/2)+O(N),可以得到该算法的时间为O(NlogN),在用分治法之前首先对Y坐标进行冒泡排序,将左右|d|范围里的点按Y值排序,然后依次从每个点出发做水平线,并在其之上d的距离做水平线,这样得到了一个2d*d 的矩形,显然,在此矩形之外的点无需开率啦,可以证明,矩形内最多容下8个点(包括自己本身)。
所以意味着在排好序的Y坐标点中,只需要考虑其后的7个点就行了,此外已有人证明了事实上只需要考虑其后的4个点就行啦。
可见,这些的时间复杂度最多Q (N)。
1.5 源程序及注释#include <stdio.h>#include <stdlib.h>#include <math.h>#define MAXLEN 200int init(float *x,float *y,int *ind){int n,i;while(1==scanf("%d",&n)){if(n > 1) break;printf("n invalid!\n");}for(i=0;i<n;i++){scanf("%f%f",x+i,y+i);ind[i]=i;}return n;}void pre_sort(float *x,float *y,int *ind,int n){//must finish in O(nlogn) but here using normorl sort method //bubble sortint i,j;int tmp;float tmp_y,tmp_x;for(i=0;i<n;i++)for(j=n-1;j > i;j--)if(x[j-1] > x[j]){//swap xtmp_x=x[j-1];x[j-1]=x[j];x[j]=tmp_x;//swap ytmp_y=y[j-1];y[j-1]=y[j];y[j]=tmp_y;//swap ind no need now!/*tmp=ind[j-1];ind[j-1]=ind[j];ind[j]=tmp;*/}for(i=0;i<n;i++)for(j=n-1;j > i;j--)if(y[j-1] > y[j]){//swap ytmp_y=y[j-1];y[j-1]=y[j];y[j]=tmp_y;//swap indtmp=ind[j-1];ind[j-1]=ind[j];ind[j]=tmp;}}float get_pair_len(float x1,float y1,float x2,float y2){return sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));}void find_closest_pair(int st,int ed,float *x,float *y,int *ind,float *closest,float *x1,float *y1,float *x2,float *y2){//key codeif(ed-st == 1){//only 2 point*closest=get_pair_len(x[ind[0]],y[0],x[ind[1]],y[1]);*x1=x[ind[0]];*y1=y[0];*x2=x[ind[1]];*y2=y[1];}else if(ed-st ==2){//only 3 pointfloat len;*closest=get_pair_len(x[ind[0]],y[0],x[ind[1]],y[1]);*x1=x[ind[0]];*y1=y[0];*x2=x[ind[1]];*y2=y[1];len=get_pair_len(x[ind[0]],y[0],x[ind[2]],y[2]);if(len < *closest){*closest=len;*x1=x[ind[0]];*y1=y[0];*x2=x[ind[2]];*y2=y[2];}len=get_pair_len(x[ind[1]],y[1],x[ind[2]],y[2]);if(len < *closest){*closest=len;*x1=x[ind[1]];*y1=y[1];*x2=x[ind[2]];*y2=y[2];}}else{//at least 4 pointsint i,cl,cr,ct;int mid;float t_c1,t_c2;float t_c1_x1,t_c1_y1,t_c1_x2,t_c1_y2;float t_c2_x1,t_c2_y1,t_c2_x2,t_c2_y2;float *yl,*yr,*yct;int *indl,*indr,*indct;mid=(st+ed)/2;yl=(float*)malloc((mid-st+1)*sizeof(float));indl=(int*)malloc((mid-st+1)*sizeof(int));yr=(float*)malloc((ed-mid)*sizeof(float));indr=(int*)malloc((ed-mid)*sizeof(int));if(!yl || !yr || !indl || !indr) exit(-2);//non enough mmfor(i=0,cl=0,cr=0;i<=ed-st;i++){//store new order y&indif(ind[i] <= mid){yl[cl]=y[i];indl[cl]=ind[i];cl++;}else{yr[cr]=y[i];indr[cr]=ind[i];cr++;}}//dividedfind_closest_pair(st,mid,x,yl,indl,&t_c1,&t_c1_x1,&t_c1_y1,&t_c1_x2,&t_c1_y2);find_closest_pair(mid+1,ed,x,yr,indr,&t_c2,&t_c2_x1,&t_c2_y1,&t_c2_x2,&t_c2_y2);if(t_c1 < t_c2){*closest=t_c1;*x1=t_c1_x1;*y1=t_c1_y1;*x2=t_c1_x2;*y2=t_c1_y2;}else{*closest=t_c2;*x1=t_c2_x1;*y1=t_c2_y1;*x2=t_c2_x2;*y2=t_c2_y2;}//get the closest pair between the two part(L&R)int v,ve;float closest_tmp;float part_line=(x[mid]+x[mid+1])/2.0;yct=(float*)malloc((ed-st+1)*sizeof(float));indct=(int*)malloc((ed-st+1)*sizeof(int));//get all the y in the rectfor(i=0,ct=0;i<=ed-st;i++)if(x[ind[i]]>part_line-*closest && x[ind[i]]<part_line+*closest ){yct[ct]=y[i];indct[ct]=ind[i];ct++;}//check followed the 4 pointsif(ct > 1){for(i=0;i< ct-1;i++){ve=(i+4 < ct-1 ? i+4:ct-1);v=i+1;while(v<=ve && yct[v]-yct[i] <=*closest){closest_tmp=get_pair_len(x[indct[i]],yct[i],x[indct[v]],yct[v]);if(closest_tmp < *closest){*closest=closest_tmp;*x1=x[indct[i]];*y1=yct[i];*x2=x[indct[v]];*y2=yct[v];}v++;}}}free(yl);free(yr);free(indl);free(indr);free(yct);free(indct);}}int main(){float X[MAXLEN],Y[MAXLEN];int IND[MAXLEN],n;n=init(X,Y,IND);float closest,x1,y1,x2,y2;pre_sort(X,Y,IND,n);find_closest_pair(0,n-1,X,Y,IND,&closest,&x1,&y1,&x2,&y2);printf("the closest value is:%-4.2f (%-4.2f,%-4.2f) (%-4.2f,%-4.2f)\n",closest,x1,y1,x2,y2);return 0;}实验二大整数乘法2.1实验内容与要求利用分治法设计一个计算两个n位的大整数相乘的算法,要求计算时间低于O(n2)。