double closest_pair(Point *p, int n) { if (n <= 1) return INFINITY; int m = n / 2; double x = p[m].x; double d = fmin(closest_pair(p, m), closest_pair(p + m, n - m)); qsort(p, n, sizeof(Point), cmp_y); Point *t = (Point *)malloc(n * sizeof(Point)); int k = 0; for (int i = 0; i < n; i++) { if (fabs(p[i].x - x) >= d) continue; for (int j = k - 1; j >= 0; j--) { double dy = p[i].y - t[j].y; if (dy >= d) break; double td = dist(p[i], t[j]); if (td < d) d = td; } t[k++] = p[i]; } free(t); return d; }解释
时间: 2023-05-29 19:03:31 浏览: 79
这段代码实现了求平面上最近点对的算法。
函数接收一个由n个点组成的Point数组p作为输入,并返回这n个点中最近的两个点之间的距离。
首先,如果n小于等于1,那么不存在最近点对,返回无穷大。
然后,将p数组按照x坐标排序,并将其分成两个子数组。递归调用closest_pair函数,分别对左右两个子数组求出最近点对的距离d。
接着,将p数组按照y坐标排序,并创建一个临时数组t来存储符合条件的点。遍历p数组,对于每个点,如果其与x的距离大于等于d,则跳过,否则在t数组中查找与该点y坐标差小于d的点,计算其与该点的距离,更新d的值为更小的那个距离。
最后,释放t数组的内存并返回最近点对的距离d。
相关问题
输入格式: 输入第一行给出一个正整数n,表示平面上的点数。随后n行,每行给出一个实数对,每个实数对表示一个点的纵横坐标值,其中第1数表示横坐标,第2数表示纵坐标。 输出格式: 输出最近点对中两个点的坐标和它们之间的距离。如果 x1+y1<=x2+y2则按 (x1,y1),(x2,y2),miniDist=Distance 输出结果,否则按 (x2,y2),(x1,y1),miniDist=Distance 输出结果c语言
以下是按照题目格式要求的C语言程序:
```c
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
typedef struct point {
double x;
double y;
} Point;
double distance(Point p1, Point p2) {
double dx = p1.x - p2.x;
double dy = p1.y - p2.y;
return sqrt(dx * dx + dy * dy);
}
int compare(const void *a, const void *b) {
Point *p1 = (Point*)a;
Point *p2 = (Point*)b;
if (p1->x != p2->x) {
return p1->x > p2->x;
} else {
return p1->y > p2->y;
}
}
double min(double a, double b) {
return a < b ? a : b;
}
double closest_pair(Point *points, int left, int right) {
if (left == right) {
return INFINITY;
} else if (left + 1 == right) {
return distance(points[left], points[right]);
}
int mid = (left + right) / 2;
double d1 = closest_pair(points, left, mid);
double d2 = closest_pair(points, mid + 1, right);
double d = min(d1, d2);
Point *strip = (Point*)malloc(sizeof(Point) * (right - left + 1));
int count = 0;
for (int i = left; i <= right; i++) {
if (fabs(points[i].x - points[mid].x) < d) {
strip[count++] = points[i];
}
}
qsort(strip, count, sizeof(Point), compare);
for (int i = 0; i < count; i++) {
for (int j = i + 1; j < count && strip[j].y - strip[i].y < d; j++) {
double dist = distance(strip[i], strip[j]);
if (dist < d) {
d = dist;
}
}
}
free(strip);
return d;
}
int main() {
int n;
printf("请输入点的数量:");
scanf("%d", &n);
Point *points = (Point*)malloc(sizeof(Point) * n);
printf("请输入每个点的坐标:\n");
for (int i = 0; i < n; i++) {
printf("第%d个点:", i + 1);
scanf("%lf%lf", &points[i].x, &points[i].y);
}
qsort(points, n, sizeof(Point), compare);
double min_distance = closest_pair(points, 0, n - 1);
Point p1, p2;
for (int i = 0; i < n - 1; i++) {
for (int j = i + 1; j < n && points[j].x - points[i].x < min_distance; j++) {
double d = distance(points[i], points[j]);
if (d == min_distance && points[i].x + points[i].y <= points[j].x + points[j].y) {
p1 = points[i];
p2 = points[j];
}
}
}
printf("最近点对是(%lf, %lf)和(%lf, %lf),距离为%lf\n",
p1.x, p1.y, p2.x, p2.y, min_distance);
free(points);
return 0;
}
```
这个程序首先会让用户输入点的数量和每个点的坐标,然后使用归并排序将点按照x坐标从小到大排序。接着,程序调用 `closest_pair()` 函数来递归地寻找平面上距离最近的点对,这个函数的实现使用了分治算法和蛮力算法的结合。最后,程序输出距离最近的点对的坐标和距离,并按照题目格式要求的顺序输出。
设计求解平面最邻近点对算法 1)数据没有事先预排序,设计算法O(n(logn)2)。 2)数据事先预排序,设计算法O(nlogn) C·语言代码
1)数据没有事先预排序,设计算法O(n(logn)2)。
算法步骤:
1. 将所有点按照x坐标从小到大排序。
2. 用一个数组存储当前已知的最近邻点对,初始化为无穷大。
3. 对于每个点i,从i+1开始遍历所有点j,如果j的x坐标和i的x坐标之差大于当前最短距离,则跳过j。
4. 对于每个点i,从i+1开始遍历所有点j,如果j的y坐标和i的y坐标之差大于当前最短距离,则跳过j。
5. 对于每个点i,从i+1开始遍历所有点j,计算点i和点j之间的距离,如果比当前最短距离小,则更新最近邻点对数组。
6. 返回最近邻点对数组。
C语言代码:
```
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
struct point {
double x;
double y;
};
int cmp(const void* a, const void* b) {
struct point* pa = (struct point*)a;
struct point* pb = (struct point*)b;
if (pa->x < pb->x) return -1;
if (pa->x > pb->x) return 1;
return 0;
}
double dist(struct point a, struct point b) {
double dx = a.x - b.x;
double dy = a.y - b.y;
return sqrt(dx * dx + dy * dy);
}
void closest_pair(struct point* p, int n, struct point* best_pair) {
int i, j, k;
double d;
qsort(p, n, sizeof(struct point), cmp);
d = dist(p[0], p[1]);
best_pair[0] = p[0];
best_pair[1] = p[1];
for (i = 0; i < n; i++) {
for (j = i + 1; j < n && p[j].x - p[i].x < d; j++) {
double d_ij = dist(p[i], p[j]);
if (d_ij < d) {
d = d_ij;
best_pair[0] = p[i];
best_pair[1] = p[j];
}
}
}
}
int main() {
struct point p[] = {{1, 2}, {3, 4}, {5, 6}, {7, 8}};
int n = sizeof(p) / sizeof(p[0]);
struct point best_pair[2];
closest_pair(p, n, best_pair);
printf("(%g,%g) (%g,%g)\n", best_pair[0].x, best_pair[0].y, best_pair[1].x, best_pair[1].y);
return 0;
}
```
2)数据事先预排序,设计算法O(nlogn)。
算法步骤:
1. 用一个数组存储当前已知的最近邻点对,初始化为无穷大。
2. 对于每个点i,从i+1开始遍历所有点j,计算点i和点j之间的距离,如果比当前最短距离小,则更新最近邻点对数组。
3. 返回最近邻点对数组。
C语言代码:
```
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
struct point {
double x;
double y;
};
double dist(struct point a, struct point b) {
double dx = a.x - b.x;
double dy = a.y - b.y;
return sqrt(dx * dx + dy * dy);
}
void closest_pair(struct point* p, int n, struct point* best_pair) {
int i, j, k;
double d;
d = INFINITY;
for (i = 0; i < n; i++) {
for (j = i + 1; j < n && p[j].y - p[i].y < d; j++) {
double d_ij = dist(p[i], p[j]);
if (d_ij < d) {
d = d_ij;
best_pair[0] = p[i];
best_pair[1] = p[j];
}
}
}
}
int main() {
struct point p[] = {{1, 2}, {3, 4}, {5, 6}, {7, 8}};
int n = sizeof(p) / sizeof(p[0]);
struct point best_pair[2];
closest_pair(p, n, best_pair);
printf("(%g,%g) (%g,%g)\n", best_pair[0].x, best_pair[0].y, best_pair[1].x, best_pair[1].y);
return 0;
}
```
阅读全文