zoukankan      html  css  js  c++  java
  • 凸包问题——Graham Scan

    Graham Scan 概述:

    对于凸多边形的定义不在这里做详细叙述,这里给出算法的实现原理。

    Step 1:

    找出x值最小的点的集合,从其中找出y值最小的点作为初始点

    Step 2:

    获得新序列后,p[n]=p[1]

    Step 3:

    把p[0],p[1],p[2]放入一个栈,从i=3循环到i=n-1,取栈顶两个元素和p[i]连线,如果未形成左旋,栈顶元素退栈,直到栈中元素仅剩两个。

    将p[i]压入栈。

    C++代码:

    #include <algorithm>
    #define MAX_N 100000000
    
    int top;//凸包的顶点个数
    typedef std::pair<int, int> point;
    int dis(point p1, point p2)//两点的距离的平方
    {
        return (p1.first - p2.first)*(p1.first - p2.first) + (p1.second - p2.second)*(p1.second - p2.second);
    }
    point p[MAX_N];
    //向量p0p1和向量p0p2的叉积
    int  multi(point p1, point p2, point p0)
    {
        //x1*y2-x2*y1
        return (p1.first - p0.first) * (p2.second - p0.second) - (p2.first - p0.first) * (p1.second - p0.second);
    }
    bool cmp(point a, point b)
    {
        //点b的极角更大
        if (multi(a, b, p[0]) > 0)
            return true;
        //共线
        if (multi(a, b, p[0]) == 0 && dis(a, p[0]) < dis(b, p[0]))
            return true;
        return false;
    }
    //Graham_scan的精华
    void Graham_scan(point p[], point stack[], int n)
    {
        int i, k = 0;
        top = 2;
        //寻找最下且偏左的点
        for (i = 1;i < n;i++)
            if (p[i].second < p[k].second || ((p[i].second == p[k].second) && (p[i].first < p[k].first)))
                k = i;
        //将该点指定为p[0];
        std::swap(p[0], p[k]);
        //按极角从小到大,距离偏短进行排序,此处注意p[0]
        std::sort(p[1], p[n - 1], cmp);
        //核心,方便起见,这里使用我们自建的stack
        stack[0] = p[0], stack[1] = p[1], stack[2] = p[2];
        for (i = 3;i < n;i++)
        {
            while (top > 1 && multi(p[i], stack[top], stack[top - 1]) >= 0)
                top--;
            stack[++top] = p[i];
        }
    }
     
  • 相关阅读:
    十大经典排序算法(动图演示) 转发自:一像素 原链接:https://www.cnblogs.com/onepixel/articles/7674659.html 个人收藏所用 侵删
    java数据类型关系及关系
    排序算法-冒泡排序
    python导入不同目录下的自定义模块
    排序算法-选择排序
    python之GUI编程-tkinter学习
    python学习相关软件安装
    mysql-8.0-winx64安装以及修改密码
    win2008环境mysql主从配置
    Linux查看文件指定某些行的内容
  • 原文地址:https://www.cnblogs.com/cielosun/p/5654542.html
Copyright © 2011-2022 走看看