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

问题:输入平面上的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阶段)提供的帮助不够大,也就是提供有序序列还有不需要遍历所有点就能生成大凸包。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值