分治法实现最近对问题

分治法----最近对问题

问题描述:

  • 已知有n个点的集合,找出其中最近的一对并返回其最近距离。

解题思路:

  • 这道题的排序是对存入数组的下标进行操作的。
  • 其思路首先是得出所要求的点的个数,再生成随机的点,然后再将所要求的点的坐标依次放入一个结构体数组中,再分别将第一次和最后一次存入的数组的数组下标作为分治法要求的左边界和右边界,再求得其中间的边界,通过递归调用左边界和右边界返回左边界和右边界中的最近点的距离(d=min(d1,d2))。
  • 最近点还有可能在两个集合之间(一个在左边界一个在右边界)。且距离小于d,然后返回最小的距离。

分治法实现最近对问题_第1张图片

// 190506分治法求最近对.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include"math.h"
#include"stdlib.h"

#define min(x,y) (x

#define MAX 10000

typedef struct node{

	int x;
	int y;

}z[MAX];//并命名为一个关于坐标的数组
double distance(node z1, node z2)
{

	double t;
	t = (z1.x - z2.x)*(z1.x - z2.x) + (z1.y - z2.y)*(z1.y - z2.y);

	return sqrt(t);

}//返回距离
double division(node s[], int left, int right)
{
	if (right - left == 1)//当只有两个点时
	{

		return distance(s[right], s[left]);
	}
	if (right - left == 2)//当只有三个点时
	{
		double d1 = distance(s[right], s[left]);
		double d2 = distance(s[right], s[left + 1]);
		double d3 = distance(s[left + 1], s[left]);
		d2 = min(d1, d2);
		d3 = min(d2, d3);//互相两两比较找出三个点的最短距离
		return d3;
	}
	int m = (right + left) / 2;
	int i, j;
	double d1 = division(s, left, m);
	double d2 = division(s, m + 1, right);
	double d = min(d1, d2);
	while (d< s[m].x - s[left].x  &&left <= right)//排除x之差大于d的坐标并且小于右边边界,筛选距离最小的坐标
	{
		left++;
	}
	while (d < s[right].x - s[m].x&&right >= left)
	{
		right--;

	}
	double d3;
	for (i = left; i <= right; i++){
		for (j = i + 1; j <= right; j++)
		{
			if (s[j].y - s[i].y >= d){

				break;//排除y之差大于d的坐标
			}

			else {

				d3 = distance(s[i], s[j]);
				if (d3 < d)
					
					d = d3;
			

			}
		}
	}


	return d;

}


void main()
{
	struct node z[MAX];
	int i, j;
	int n;
	printf("请输入要生成的点数:");
	scanf_s("%d", &n);
	if (n < 2)
	{
		printf("输入错误");
		exit(0);
	}
	for (i = 0; i < n; i++)
	{		
		z[i].x = rand() % 100 + 1;//随机生成100以内的数字
		z[i].y = rand() % 100 + 1;
		for (j = 0; j < i; j++)
		{
			if (z[j].x == z[i].x&&z[i].y == z[j].y){
				
				i--;//检验点集是否重复
				break;
			}

		}

	}
	for (i = 0; i < n; i++)
	{
		printf("(%d,%d)    ", z[i].x, z[i].y);

	}
	printf("最近对最小距离为%lf\n", division(z, 0, n - 1));



}
  • 运行结果:
    分治法实现最近对问题_第2张图片

你可能感兴趣的:(算法块,分治法实现最近对)