The recent point pairing problem involves sorting the points in ascending order by x or y. The author tries to optimize the sorting method. The first thing that comes to mind is naturally merge sort. After all, the core idea of merge sort is also the divide and conquer method, but merge sort is more suitable for cases with more cardinality. Finally, the author changed the idea as follows: when the value of the total number of points n is less than 50, the insertion sort is used, and when the value of n is greater than 50, the merge sort is used. The code is as follows:
void MergeSort(point *a, int p, int r,bool sort_x_y) { if ((rp)>=50) // Insertion sort for arrays with less than 50 data { int q = (p+r)/2; MergeSort(a, p, q,sort_x_y); MergeSort(a, q+1, r),sort_x_y; Merge(a, p, q, r,sort_x_y); }else { InsertionSort(a+p, r-p+1,sort_x_y); } } double ClosestPoint(point s_array[],int low,int high,point min_point[]){ double d1,d2,d3,d; int mid,i,j,index; double x1,y1,x2,y2; //Record the position of the point pair point P[high-low+1],temp1[2],temp2[2]; //auxiliary space if(high-low==1){ //The case of two points min_point[0].x=s_array[low].x;min_point[0].y=s_array[low].y; min_point[1].x=s_array[high].x;min_point[1].y=s_array[high].y; return Points_Distance(s_array[low],s_array[high]); } if(high-low==2){ //The case of three points d1=Points_Distance(s_array[low],s_array[low+1]); d2=Points_Distance(s_array[low+1],s_array[high]); d3=Points_Distance(s_array[low],s_array[high]); if((d1<d2)&&(d1<d3)){ min_point[0].x=s_array[low].x;min_point[0].y=s_array[low].y; min_point[1].x=s_array[low+1].x;min_point[1].y=s_array[low+1].y; return d1; } else if(d2<d3){ min_point[0].x=s_array[low+1].x;min_point[0].y=s_array[low+1].y; min_point[1].x=s_array[high].x;min_point[1].y=s_array[high].y; return d2; } else { min_point[0].x=s_array[low].x;min_point[0].y=s_array[low].y; min_point[1].x=s_array[high].x;min_point[1].y=s_array[high].y; return d3; } } mid=(low+high)/2; //Recursive in other cases d1=ClosestPoint(s_array,low,mid,min_point); temp1[0]=min_point[0]; temp1[1]=min_point[1]; d2=ClosestPoint(s_array,mid+1,high,min_point); temp2[0]=min_point[0]; temp2[1]=min_point[1]; if(d1<d2){ d=d1; min_point[0]=temp1[0]; min_point[1]=temp1[1]; } else { d=d2; min_point[0]=temp2[0]; min_point[1]=temp2[1]; } index=0; for(i=mid;(i>=low)&&((s_array[mid].x-s_array[i].x)<d);i--) //点集合p1 P[index++]=s_array[i]; for(i=mid+1;(i<=high)&&((s_array[i].x-s_array[mid].x)<d);i++) //点集合p2 P[index++]=s_array[i]; MergeSort(P,P+index,Assist_y); //Ascending order for(i=0;i<index;i++){ for(j=j+1;j<index;i++){ if((P[j].y-P[i].y)>=d) break; else { d3=Points_Distance(P[i],P[j]); if(d3<d){ min_point[0].x=P[i].x;min_point[0].y=P[i].y; min_point[1].x=P[j].x;min_point[1].y=P[j].y; d=d3; } } } } return d; } int main(){ //set of set points int n,dimension; double min_distance; cout<<"Number of input points:\n"; //Number of input points cin>>n; point s_array[n]; L1: cout<<"Please input the plane where the point is located (1-dimensional input 1, 2-dimensional input 2): "; cin>>dimension; if(dimension==1) for(int i=0;i<n;i++) { cout<<"Please enter the distance of the "<<i+1<<" point from the origin"<<endl; cin>>s_array[i].x; s_array[i].y=0; } else if(dimension==2) for(int i=0;i<n;i++) { cout<<"Please enter the coordinates of the "<<i+1<<" point (separated by spaces)"<<endl; cin>>s_array[i].x>>s_array[i].y; } else { cout<<"The input plane is invalid"<<endl; goto L1; } MergeSort(s_array,s_array+n,Assist_x); point min_point[2]; min_distance=ClosestPoint(s_array,0,n-1,min_point); cout<<"最小距离点对为:("<<min_point[0].x<<","<<min_point[0].y<<"),("<<min_point[1].x<<","<<min_point[1].y<<")"; cout<<"The minimum distance is:\n"<<min_distance; return 0; }
The author did not give the InsertionSort() and Merge() functions, because the amount of code of these two functions is larger than expected, and the sorting according to x/y needs to be judged, and function overloading needs to be performed. Here the author recommends the sort() function to everyone, just use #include <algorithm> sort to use it. The sorting method it uses is similar to the quicksort method. The time complexity is n*log2(n), and the execution efficiency is higher.
For example, in the above author's code, only two functions need to be added as follows:
bool Assist_y(point a,point b){ //sort by y ascending return a.y<b.y; } bool Assist_x(point a,point b){ //sort by x ascending return a.x<b.x; }
transfer:
sort(s_array,s_array+n,Assist_x);//In ascending order by x sort(s_array,s_array+n,Assist_y);//In ascending order by y