算法 最近对问题完整代码分析

#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  的用法。

当然最最重要的是 分治法 求解问题。 当一个复杂问题分解到很小时候可以很容易求解那么分治法就是很好的选择。

还有就是递归的理解和越界问题。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值