算法笔记(二)凸包问题convex hull

1、问题定义:

(1)输入:平面上的n个点的集合Q ;输出: CH(Q),即Q的凸包

(2)Q的凸包:是一个最小凸多边形 P,Q的点在P上或者在P内

(3)凸多边形P: 连接P内任意两点的边都在P内

2、基本思想:

(1)当沿着凸包逆时针漫游时,总是向左转;

(2)在极坐标系下按照极角大小排列,然后按逆时针方向漫游点集,去除非凸包顶点(非左转点)

3、伪代码:

4、时间复杂性分析:T(n)=O(nlogn)

 

5、正确性分析:

【定理】设n个二维点的集合Q是Graham-Scan算法的输入,|Q|>=3,则算法结束时,栈S中自底到顶存储CH(Q)的顶点(按照逆时针顺序)

【证明】使用循环不变量方法

【循环不变量】在处理第i个顶点之前, 栈S中自底到顶存储CH(Qi-1)的顶点

【数学归纳法】

处理i=3之前,栈S中包含了Qi-1=Q2={p0,p1,p2 }中的顶点,这三个点形成了一个CH。循环不变量为真。

设在处理第i(i>=3)个顶点之前, 循环不变量为真,即栈S 中自底到顶存储CH(Qi-1)的顶点。

往证: 算法执行5~7步之后,栈S中自底到顶存储CH(Qi)的顶点。

(1)5~6步while循环执行结束后,第7步将pi压入栈之前,设栈顶元素为pj,次栈顶元素为pk,则此时,栈中包含了与for循环的第j轮迭代后相同的顶点,即CH(Qj),循环不变量为真。

(2)执行第7步之后, pi入栈, 则栈S中包含了CH(Qj∪{pi})中的顶点,且这些点仍按逆时针顺序,自底向上出现在栈中。(此时考虑是否CH(Qj∪{pi })=CH(Qi)?)

(3)对于任意一个在第i轮迭代中被弹出的栈顶点pt,设 pr为紧靠pt的次栈顶点,pt被弹出当且仅当pr 、pt 、pi构成非左移动。因此, pt不是CH(Qi ) 的一个顶点,即CH(Qi−{pt })= CH(Qi )。

(4)设Pi为for循环第i轮迭代中被弹出的所有点的集合,则有CH(Qi−Pi )= CH(Qi )

(5)又 Qi−Pi= Qj∪{pi },故有CH(Qj∪{pi })= CH(Qi−Pi )= CH(Qi )

(6)即得到:一旦将pi压入栈后, 栈S中恰包含CH(Qi )中的顶点, 且按照逆时针顺序,自底向上排列。

i=n+1,栈S中自底到顶存储CH(Qn )的顶点,算法正确。

证明完毕。

6、分治算法Divide-and-Conquer:

【边界条件】(时间复杂性为O(1))

(1)如果|Q|<3, 算法停止;

(2)如果|Q|=3, 按照逆时针方向输出CH(Q)的顶点;

【Divide】(使用O(n)算法求中值)

选择一个垂直于x-轴的直线把Q划分为基本相等的两个集合QL和QR,QL在QR的左边;

【Conquer】(时间复杂性为2T(n/2))

递归地为QL和QR构造CH(QL)和CH(QR);

【Merge】(时间复杂性为O(n))

(1)找到QL和QR中y坐标最小的点p (假设在QL中);

(2)在CH(QR)中找与p的极角最大和最小顶点u和v;

(3)构造如下三个点序列:a. 按逆时针方向排列的CH(QL)的所有顶点;b. 按逆时针方向排列的CH(QR)从v到u的顶点;c. 按顺时针方向排列的CH(QR )从v到u的顶点;

(4)合并上述三个序列;

(5)在合并的序列上应用Graham-Scan。

7、时间复杂性:

T(n)=2T(n/2)+O(n)

使用Master定理可知,T(n)=O(nlogn)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

gasic

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值