#include <iostream>
//#include <algorithm>
#include<cmath>
using namespace std;
const int n=10;
struct point{ //点
int x;
int y;
};
double Distance(point a, point b){ //计算两点之间的距离
return sqrt((a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y));
}
//int cmp(const void *a, const void *b)
//{return (*(point *)a).y >(*(point *)b).y ? 1 : -1;}
int Partition(point r[], int first, int end){ //快速排序算法中划分区间
int i = first, j = end;
while (i < j){
while (i < j&&r[i].y <= r[j].y) j--;
if (i < j){
point temp = r[i]; r[i] = r[j], r[j] = temp;
i++;
}
while (i < j&&r[i].y <= r[j].y) i++;
if (i < j){
point temp = r[i]; r[i] = r[j], r[j] = temp;
j--;
}
}
return i;
}
void QuickSort(point r[], int first, int end){ //快速排序
int pivot;
if (first < end){
pivot = Partition(r, first, end);
QuickSort(r, first, pivot - 1);
QuickSort(r, pivot + 1, end);
}
}
double Closest(point S[], int low, int high){ //最近对划分计算
double d1, d2, d3, d;
int mid, i, j, index;
point P[n]; //存放 P1 P2
if (high - low == 1){ //只有两点
return Distance(S[low], S[high]);
}
if (high - low == 2){ //三个点
d1 = Distance(S[low], S[low + 1]);
d2 = Distance(S[low + 1], S[high]);
d3 = Distance(S[low], S[high]);
if ((d1 < d2) && (d1 < d3)) return d1;
else if (d2 < d3) return d2;
else return d3;
}
mid = (low + high) / 2; //求出中值
d1 = Closest(S, low, mid); //递归求P1
d2 = Closest(S, mid + 1, high); //递归求P2
if (d1 <= d2) d = d1;
else d = d2;
index = 0; //P1和P2之间最近对
for (i = mid; (i >= low) && (S[mid].x - S[i].x < d); i--)
P[index++] = S[i];
for (i = mid + 1; (i <= high) && (S[i].x - S[mid].x < d); i++)
P[index++] = S[i];
QuickSort(P , 0, index - 1); //按y上升排序
//qsort(P, 100, sizeof(P[0]), cmp);//不正确
for (i = 0; i < index; i++){
for (j = i + 1; j < index; j++){
if (P[j].y - P[i].y >= d)
break;
else{d3 = Distance(P[i], P[j]);
if (d3 < d) d = d3;
}
}
}
return d;
}
int main(){
while (1) //循环测试
{
int n, i;
double answer;
cout << "输入点个数" << endl;
cin >> n;
while (n <= 1){ //输入错误重新输入
cout << "点数不能小于2请重新输入" << endl;
cin>>n;
}
point *P; //new 和 delete[] 要配对使用
P = new point[n];
for (i = 0; i < n; i++){
cout << "input x.y:\n";
cin >> P[i].x>> P[i].y;
}
for (i = 0; i < n; i++){
cout <<"点"<<i+1<<"坐标"<< P[i].x<<" "<< P[i].y<<" ";
}
answer = Closest(P, 0, n-1); //输入n-1为了不越界
cout << "最近对为" << answer << endl;
delete[] P;
}
return 1;
}
在这个算法中学到了 struck 结构体函数的定义和用法他和数组的区别。 以及 宏#define 定义的常量预编译 调用 和const 定义的常量 变量的优秀之处。
sort 快速排序算法qsort 还有int *p=new int[n] 和 delete[] p 的用法。
当然最最重要的是 分治法 求解问题。 当一个复杂问题分解到很小时候可以很容易求解那么分治法就是很好的选择。
还有就是递归的理解和越界问题。