最近点计算(二)

之前的最近点计算,是使用暴力搜索的,所需的时间让人不可接受

利用哈希算法,将单位正方形分成一个网格,设置一个链表的二维数组,每个网格正方形对应一个表,选择的网格足够精巧,与已知距离为d之内的所有点或落于统一网格内,或落于邻接网格内!

解读:就是将距离哈希化,对应的坐标落在某一个格子里面,每个格子都有一个头指针,存储映射到其内的坐标,相邻的坐标之差都是比1来得小的,所以只需要与周围的8个格子内的坐标及其当前格子内的坐标进行比较即可

补充:

二维数组的建立:

link **malloc2d(int r,int c)
{
	int i;
	link **t = (link **)malloc(r*sizeof(link *));
	for(i = 0;i < r;i++)
		t[i] =  (link *)malloc(c*sizeof(link));
	return t;
}

二维数组的删除:

void Free(link **tmp,int row)
{
	int i = 0;
	for(i = 0;i < row;i++)
	{
		free(tmp[i]);
	}
	free(tmp);
}
注:t[i][j]已经就是对对应指针所指向的元素的访问,而(*t[i])与之是等价的。

代码:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

typedef struct Point
{
	float x;
	float y;
}point;


float randFloat()  
{  
	return 1.0*rand()/RAND_MAX;  
}  

float distance(Point a,Point b)  
{  
	return sqrt((a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y));  
} 


typedef struct node* link;
struct node
{
	point p;
	link next;
};

link **malloc2d(int r,int c)
{
	int i;
	link **t = (link **)malloc(r*sizeof(link *));
	for(i = 0;i < r;i++)
		t[i] =  (link *)malloc(c*sizeof(link));
	return t;
}

void Free(link **tmp,int row)
{
	int i = 0;
	for(i = 0;i < row;i++)
	{
		free(tmp[i]);
	}
	free(tmp);
}


link **grid;
int G;
float d;
int cnt = 0;

void gridinsert(float x,float y)
{
	int i,j;
	link s;
	int X = x*G + 1;
	int Y = y*G + 1;
	link t = (link)malloc(sizeof(struct node));
	t->p.x = x;
	t->p.y = y;
	for(i = X-1;i <= X+1;i++)
	{
		for(j = Y-1;j <= Y+1;j++)
		{
			for(s = grid[i][j];s!=NULL;s = s->next)
			{
				if(distance(s->p,t->p) < d)
					cnt++;
			}
		}
	}

	t->next = grid[X][Y];
	grid[X][Y] = t;
}


int main()
{
	int i,j,N;
	float x,y;
	while(1)
	{
		cnt = 0;
		scanf("%f%d",&d,&N);

		//必须用1/d
		G = ceil(1/d);//确定网格个数
		grid = malloc2d(G+2,G+2);



		for(i = 0;i <G+2;i++)
		{
			for(j = 0;j < G+2;j++)
			{
				//必须初始化,gird[i][j]相当于是一个头节点
				grid[i][j] = NULL;
			}
		}

		for(i = 0;i < N;i++)
		{
			x = randFloat();
			y = randFloat();
			gridinsert(x,y);
		}
		printf("%d shorter than %f\n",cnt,d);
		Free(grid,G+2);
	}
}



//int main()
//{
//	link *s = (link *)malloc(3*sizeof(link));
//	//是分配指针 不是分配空间!
//	s[0] = (link)malloc(sizeof(struct node));
//	s[0]->p.x = 5;
//	printf("%f\n",s[0]->p.x);
//}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值