基于循环链表的凸包增量算法研究与实现

作者:徐东;刘海见;杨健 刊名:现代计算机(专业版) 上传者:李娜

【摘要】采用循环链表构建凸包,使凸包的各顶点在增量过程中,始终处于动态变化的稳定循环链中,无差错地生成结果凸包。相比顺序表而言,每次只需修改指针,无须在内存中频繁移动顶点数据,节省大量的系统时间及内存资源,从根本上解决首尾相接的凸包动态生成问题,极好地满足程序的鲁棒性原则,代码执行效率高。

全文阅读

0引言凸包是计算几何中最普遍、最基本的一种结构,是计算几何的基本问题之一,它不仅有着自身的许多特性,而且还是构造其他几何形体的有效工具。在应用中,许多实际问题可以归结为凸包问题,在图像处理、地理信息系统、模式识别等领域中均有着广泛应用。凸包算法思想能否在计算机系统中得以高效实现,对算法的能力发挥和问题解决效率均会产生很大影响。链表是C语言程序设计中极具代表性的编程结构,许多复杂的算法问题都依赖于这种结构,也有人说,指针和链表代表了C语言。链表使用得好,不但可以大大地降低编程的代码量,提高代码质量,解决其他数据结构不能解决的问题,更能对内存的管理实现进一步的优化,使程序在执行过程中高效地使用内存,提高程序执行的整体效率。针对凸包特点,充分利用循环链表的优势,在VC环境下,很好地实现了凸包增量算法,提高了算法执行效率。1凸包增量算法描述[1~3]给定有n个点的点集S,用增量算法求S的凸包的基本思想是:每次添加一个点,构造前k个点的凸包时需要用到前k-1个点的凸包,即每次只增加一个点到已有的凸包。设S={P1,P2,…,Pn},并设S中的任意三点均不共线,其增量算法的具体步骤如下:(1)取P1,P2,P3三点围成的三角形为初始凸包CH3{P1,P2,P3};(2)fork=4tondoCHkCH({CHk-1Pk});此时会出现两种情况:若新增的点PkCHk-1,则CHk与CHk-1有相同的凸包顶点;若新增的点Pk埸CHk-1,则CHk由CHk-1中的顶点与Pk组成。判断方法如下:按照逆时针方向排列CHk-1的顶点序列,如果Pk在每条BCHk-1的左侧,则PkCHk-1;否则Pk埸CHk-1。当Pk埸CHk-1时,计算CH({CHk-1Pk}),关键点是找到由Pk到CHk-1的正切点。找正切点算法如下:fori=2tok-1doif(Pk在Pi-1Pi的左侧Pk在PiPi+1的右侧)(Pk在Pi-1Pi的右侧Pk在PiPi+1的左侧)thenPi是正切点趦趷现代计算机2014.04中正切点算法以判定点在方向线段的左、右侧为基本操作,则其算法复杂性为O(k)。最坏情况下,n个点均为凸包顶点,其增量算法的时间复杂性为3+4+…+n=O(n2)。1987年,Edelsbrunner提出了改进的增量算法,其复杂性为O(nlogn)。2编程实现2.1编程环境鉴于运行结果的可视化要求,选用VisualC++6.0编程环境,在程序设计过程中发现,在判断新点是否在原凸包内部时,使用的原MFC相关求三角形面积库函数经常不能正确判断,无法达到要求,所以,笔者自行设计。另外,为保证链表的全局性,在新建类中定义该链表。2.2对凸包链表结点的定义typedefstructHullVex{intx;//点坐标xinty;//点坐标yHullVex*next;//链表指针};2.3判断新点与原凸包位置关系的自定义函数(1)判断新点是否在原凸包中一个边的左部:LeftOn(HullVex*v0,HullVex*v1,HullVex*v2){returnarea(v0,v1,v2)>0;}务//area函数为求三角形面积函数(2)判断新点是否在原凸包的内部:PointInSide(HullVex*v0,HullVex*v1){intt;for(t=1;tnext,v1)>0){v0=v0->next;continue;}elsereturnfalse;}returntrue;}2.4构建凸包边界循环链表,形成新凸包采用增量方式,首先用三点形成一个初始凸包,之后各点将按顺序依次加入凸包,

参考文献

引证文献

问答

我要提问