c语言分治算法求最近对,分治法求解最近对问题(c++)

#include"stdafx.h"

#include

#include

#define TRUE 1

#define FALSE 0

using namespace std;

typedef struct Node//坐标点

{

double x;

double y;

}Node;

typedef struct List

{

Node* data;      //点

int count;      //点的个数

}List;

typedef struct CloseNode

{

Node a;

Node b;     //计算距离的两个点

double space;     //距离平方

}CloseNode;

int n;     //点的数目

//输入各点到List中

void create(List &L)

{

cout << "请输入平面上点的数目:\n";

cin >> n;

L.count = n;

L.data = new Node[L.count];      //动态空间分配

cout << "输入各点坐标 :x_y):" << endl;

for (int i = 0; i

cin >> L.data[i].x >> L.data[i].y;

}

//求距离的平方

double square(Node a, Node b)

{

return ((a.x - b.x)*(a.x - b.x)) + ((a.y - b.y)*(a.y - b.y));

}

//冒泡排序

void BubbleSort(Node r[], int length)

{

int change, n;

n = length; change = TRUE;

double b, c;

for (int i = 0; i

{

change = FALSE;

for (int j = 0; j

{

if (r[j].x>r[j + 1].x)

{

b = r[j].x; c = r[j].y;

r[j].x = r[j + 1].x; r[j].y = r[j + 1].y;

r[j + 1].x = b; r[j + 1].y = c;

change = TRUE;

}

}

}

}

//分治法中先将坐标按X轴从小到大的顺序排列

void paixu(List L)

{

BubbleSort(L.data, L.count);   //调用冒泡排序

}

//左右各距中线d的区域的最近对算法

void middle(const List & L, CloseNode &cnode, int mid, double midX)

{

int i, j;    //分别表示中线左边,右边的点

double d = sqrt(cnode.space);

i = mid;

while (i >= 0 && L.data[i].x >= (midX - d))    //在左边的d区域内

{

j = mid;

while (L.data[++j].x <= (midX + d) && j <= L.count)    //在右边的d区域内

{

if (L.data[j].y(L.data[i].y + d))   //判断纵坐标是否在左边某固定点的2d区域内

continue;

double space = square(L.data[i], L.data[j]);

if (cnode.space>space)    //在满足条件的区域内依次判断

{

cnode.a = L.data[i];

cnode.b = L.data[j];

cnode.space = space;

}

}

--i;

}

}

//分治法求最近对

void DivideConquer(const List &L, CloseNode &closenode, int begin, int end)

{

if (begin != end)

{

int mid = (begin + end) / 2;     //排列后的中间的那个点

double midX = L.data[mid].x;

DivideConquer(L, closenode, begin, mid);      //继续在左半边用分治法求最近对

DivideConquer(L, closenode, mid + 1, end);      //继续在右半边用分治法求最近对

middle(L, closenode, mid, midX);               //判断左右各距中线d的区域,是否有最近对

}

}

void main()

{

//初始化

List list;

CloseNode closenode;

closenode.space = 10000;

create(list);

cout << "各点坐标为:" << endl;

for (int i = 0; i

cout << "X=" << list.data[i].x << "   Y=" << list.data[i].y << "\n";

cout << "用分治法求最近对:" << endl;

paixu(list);

cout << "经过排序后的各点:" << endl;

for (int j = 0; j

cout << "X=" << list.data[j].x << "   Y=" << list.data[j].y << "\n";

DivideConquer(list, closenode, 0, list.count - 1);

cout << "最近对为点 (" << closenode.a.x << "," << closenode.a.y << ")和点(" << closenode.b.x << "," << closenode.b.y << ")\n" << "最近距离为: " << sqrt(closenode.space) << endl;

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值