不太明白题主的意思,不过:
如果这些点可以形成一个凸多边形的话,就凸包就行,算法多了去了Jarvis March, Graham Scan, Quick Hull, randomized incremental construction……算完也就把顺序排出来了。
如果不是的话,请首先弄明白自己的需求,定义一个良序,因为有很多种方法可以连出一个边不自交的多边形,排序结果不唯一。当然,如果题主不是很介意,生成任意一个不自交的多边形都可以,我提一种简单粗暴的增量算法:
1、取任意不共线的三点连成一个三角形X(在你给的例子中,比如取1-4-5-1)。
2、然后遍历剩余的点(记为P)和已有的多边形X的边(记为AB),若三角形ABP中不含其他点,把点P插入已有的多边形X中(原来的边AB变成AX, XB两条边)。
3、重复步骤2,直到选完所有顶点。
嗯,复杂度是O(N^4)……
=============================
好吧,再提一个更快的分治算法:
1、预处理:先把所有点按x坐标从左到右排序,时间为O(NlgN)。
2、分治:用一条竖线把所有的点切成两半,分别递归执行本算法,得到左右两边的多边形X和Y。
3、合并:把X的最低点重新连到Y的最低点,再把Y的左链的次低点连到X的右链的次低点。(左、右链就是把整个多边形(一个圈)从最高点和最低点断开,拆成两部分啦!)
分
治、合并部分的复杂度是T(N) = 2*T(N/2) + O(N),也即T(N) =
O(NlgN),算上预处理部分,总的复杂度也是O(NlgN)。(其实合并部分如果做得好可以O(1)完成,因此分治+递归只需要O(N)时间。但由于
预处理就已经需要O(NlgN)的时间了,后面分治做得快也没用啊……)
举个例子,在题主那张图里,递归处理左右两部分,得到多边形X:
1-5-4-1(其中1-5叫左链,5-4-1叫右链)和Y:
6-2-3-6(其中6-2-3叫左链,3-6叫右链)。然后合并:连接5-3(多边形X和Y的最低点,原来的连线5-4自动断开),连接2-4(Y左链
的次低点和X右链的次低点,原来的连线2-3自动断开)。得到的多边形就是1-5-3-6-2-4-1。
得出的多边形大概像是城墙的形状,像是若干个汉字“凹”连接起来的。我画个示意图:
![]()
===============
合并算法稍有问题,需要再修改,不过大体是对的。
=======================继续更=========================
想到了一个非常简单的算法哈哈哈:
1、对所有点按照x坐标(x相同时按y)从小到大排序,把最左边的点记为A(若有多个取最下方的点),最右边的点记为B(若有多个取最上方的点)。2、构造上链: 把所有在直线AB上方的点按x坐标(x相同时按y)从小到大连接起来;3、构造下链:对位于直线AB下方的点同样处理。最后输出的时候注意把下链颠倒一下(连的时候是从A连到B的,输出的时候从B到A输出)就行。
正确性显而易见:上链内部是边不交的(因为边的端点的x坐标从小到大排列),下链同理,上下链之间也不交(因为分处直线AB两侧,没法交)。
然后就完了!时间复杂度O(NlgN),而且非常好写!示意图如下: