凸包

来源:互联网 发布:淘宝联盟的导购推广 编辑:程序博客网 时间:2024/04/29 13:49

点集Q的凸包是一个最小的凸多边形P,满足Q中的每个点或者在P的边界上,或者在P的内部。

主要介绍Graham扫描算法,时间复杂度为O(nlgn)。

算法:通过设置一个关于候选点的堆栈S来解决凸包问题。输入集合Q中的每个点都压入栈一次,非CH(Q)中顶点的点最终被弹出堆栈。当算法终止时,堆栈

S中仅包含CH(Q)中的顶点,其顺序为各点在边界上出现的逆时针方向排序的顺序。

Graham_Scan(Q):

int Graham(){    int i, top, tmp = 0;    for(i = 1; i < n; i++)        if((map[i].y<map[tmp].y) || (map[i].y == map[tmp].y && map[i].x < map[tmp].x))            tmp = i;    Point p = map[tmp];    map[tmp] = map[0];    map[0] = p;    sort(map + 1, map + n, cmp);    S[0] = map[0];    S[1] = map[1];    S[2] = map[2];    top = 2;    for(i = 3; i < n; i++)    {        while(direction(S[top - 1],map[i],S[top]) > 0)            top--;        S[++top] = map[i];    }    return top;}

int direction(Point p0, Point p1, Point p2){    return (p1.x - p0.x)*(p2.y - p0.y) - (p2.x - p0.x)*(p1.y - p0.y);}

int cmp(Point p1, Point p2){    if(direction(map[0],p1,p2) > 0)        return 1;    else if(direction(map[0],p1,p2) == 0 && (dist(map[0],p1)-dist(map[0],p2) < 0))        return 1;    return 0;}


原创粉丝点击