首先是凸包的定义,假设平面内有一些点,这些点中的一部分组成一个多边形,将其他的点都包含起来,当这个多边形是凸多边形的时候,我们就把他当成是一个凸包。
解决凸包问题有很多种算法,比较常见的有O(n^3)的暴力穷举算法以及O(nlogn)d的分治算法,这里讲的是一个时间复杂度为O(nlogn)的Graham扫描法。
算法
图中点的编号排序
首先建立一个极坐标系,选取所有点中最左下的点作为极点,将所有的点按照逆时针方向进行排序,角度相同的点,距离极点小的点排在前面。
依次寻找凸包上面的点
用栈来存储凸包的点(因为我们要读取栈顶的两个点,所以不用STL中的queue,而是用数组建栈),依次考察排序好的点,判断是否弹出栈顶元素。考察规则:从栈中取出栈顶的两个点,两点连接成一条直线,然后判断当前考虑的点在再这条直线的左边还是右边(利用叉乘进行判断),在左边表示这个点在凸包上,入栈;在右边表示当前栈顶元素不是凸包上的点,将这个点出栈,然后继续取出栈顶的两个点进行考虑,直到可以将这个点加入栈中。
模板
1 | struct point |