zoukankan      html  css  js  c++  java
  • 分治法求解最近对问题(c++)

    #include"stdafx.h"
    #include<iostream>
    #include<cmath>
    #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 << "请输入平面上点的数目: ";
     cin >> n;
     L.count = n;
     L.data = new Node[L.count];      //动态空间分配
     cout << "输入各点坐标 :x_y):" << endl;
     for (int i = 0; i<L.count; ++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<n - 1 && change; ++i)
     {
      change = FALSE;
      for (int j = 0; j<n - i - 1; ++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) || 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<list.count; ++i)
      cout << "X=" << list.data[i].x << "   Y=" << list.data[i].y << " ";
     cout << "用分治法求最近对:" << endl;
     paixu(list);
     cout << "经过排序后的各点:" << endl;
     for (int j = 0; j<list.count; ++j)
      cout << "X=" << list.data[j].x << "   Y=" << list.data[j].y << " ";
     DivideConquer(list, closenode, 0, list.count - 1);
     cout << "最近对为点 (" << closenode.a.x << "," << closenode.a.y << ")和点(" << closenode.b.x << "," << closenode.b.y << ") " << "最近距离为: " << sqrt(closenode.space) << endl;
    }
     
  • 相关阅读:
    音频文件的属性
    判断UITextField.text是否为空(转)
    digital audio properties
    对scrollView的属性contentSize contentOffset contentInset个人理解
    OC定义变参函数
    va_list、va_start、va_arg、va_end的原理与使用(转载)
    游标笔记
    oracle中删除重复数据
    IIS无法启动,错误代码127[转自Alibaba DBA Team]
    推进游标是Fetch不是Petch!~!
  • 原文地址:https://www.cnblogs.com/penglei-it/p/5220139.html
Copyright © 2011-2022 走看看