Finding the convex hull(求解凸包问题)

文章介绍了Graham-Scan算法用于找到一组点在平面上的凸包。该算法首先通过极角排序点集,然后遍历并移除非左转点,确保凸包的逆时针方向。在最坏情况下,时间复杂性为O(nlogn)。文章还讨论了如何利用分治思想改进算法,以及在合并凸包时如何优化,但认为原算法的分治改进在Merge阶段效率提升有限。
摘要由CSDN通过智能技术生成

问题:输入平面上的n个点的集合Q,需输出CH(Q),即Q的凸包。

Graham-Scan算法:

 当我们沿着凸包逆时针漫游时,在拐角处总是向左转。因此我们assume所有点在极坐标系下按照极角大小排列,我们逆时针去遍历所有点,去除非凸包的顶点(也就是非左转点)

 p0,p1和pn一定在最后生成的凸包中。先入栈3个(3个顶点一定可以生成一个凸包);

如果next-to-top元素、top元素与新元素形成了非左移动(右拐了),就出栈top元素;一直出栈top元素直到next-to-top元素、top元素与新元素形成左移动。

将pi点进栈并判断下一个点,直到点pn判断完。

时间复杂性为O(nlogn):

S1是Selection问题,O(n)解决;S2普通排序,需要O(nlogn);S3O(1);S4-7:貌似最坏的时间是外层O(n),内层也O(n),总体上是O(n²),但事实上每个元素至多进栈一次、出栈一次。所以总体上这三步耗费的时间最多为O(n)。(可以想象一下最坏情况,判定到pn的时候需要把前面n-2个点全部出栈,这也意味着p4-p(n-1)加入时都不需要出栈)

算法正确性分析:

 往证CH(Qj∪{pi})=CH(Qi):

上图倒数第二行写错了,实际上是:

 注意:pj是在while循环结束后设的栈顶元素。也就是说for循环的j+1次迭代到第i次迭代向外弹出点这个动作结束之后留下的符合左移动的点,Qi减去pk的加和后正好就是Qj加点pi。

 如何使用分治思想对Graham算法进行改进?

 如何Merge?

 获得3段相对于p点来说极角逆时针增大的序列。有了相对的大小位置再进行合并的话只需要O(n)的时间复杂度。比如先扫一遍获得最大的有序序列<g,h,i,j,k>花θ(n),将,其余序列逐个插入。如<a,b,c,d>,a如果在g,h后面那bcd也不需要和gh做比较了。最多也只比较了O(2n)而已。

 比起不分治的Graham算法,时间复杂度也没有优到哪儿去。个人觉得是因为两个凸包并没有为合成一个大凸包(Merge阶段)提供的帮助不够大,也就是提供有序序列还有不需要遍历所有点就能生成大凸包。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值