【问题标题】:Sorting vertices in graph adjacency list in clockwise order按顺时针顺序对图邻接表中的顶点进行排序
【发布时间】:2014-05-16 13:18:32
【问题描述】:

我有一个表示为循环链表数组的平面图。 每个列表代表一个顶点及其相邻顶点。

我需要按顺时针平面顺序对每个邻接列表中的顶点进行排序。

我不知道该怎么做。有算法吗?

【问题讨论】:

  • 每个顶点都有平面坐标吗?如果是这样,您可以使用atan2(dir.y, dir.x),根据指向“中心”顶点的方向向量对相邻顶点进行排序。
  • 是的,如果需要,我可以找到它们。如果找不到更好的解决方案,我会这样做。在最坏的情况下,它需要 O(V^2*log(V)) 时间。不是真正可以接受的复杂性。
  • 你是怎么得出这么大的哦? IIRC,平面图中的边数为 O(V),因此该解决方案将在 O(V*log(V)) 时间内运行。
  • 我需要对每个顶点的相邻顶点进行排序 - 所以整体复杂度是 VO(Vlog(V)) = O(V^2*log(V))
  • 应该可以在没有坐标的情况下完成任务。使用坐标可能无法给出正确答案,在我的图中,很多顶点具有相同的 X 或 Y 坐标,因此与中心顶点的角度相同。

标签: c++ sorting graph adjacency-list


【解决方案1】:

由于您在 cmets 中指出您有平面坐标,因此这里有一个使用它们的解决方案(在伪代码中)。基本上,您按照从顶点到相邻顶点(a - v) 的向量的atan2 的升序对每个顶点v 的相邻顶点a 进行排序。

struct Point
{
    x, y;
};
// assume Point has overloaded arithmetic operators

void sortAdjacentVertices(Point v, list<Point> adjacentVertices)
{
    map<double, Point> sorted;
    for each (a in adjacentVertices)
    {
        Point dir = a - v;
        sorted[atan2(dir.y, dir.x)] = a;
    }
    adjacentVertices.clear();
    for each (a in sorted)
    {
        adjacentVertices.push(a.value);
    }
}

为图的每个顶点调用此函数将在 O(V * log(V)) 中运行,其中 V 是顶点的数量,假设可以在 O(1) 中获得邻接列表。这是因为每条边只被检查一次(对于有向图)或两次(对于无向图)并且number of edges in a planar graph is O(V)

【讨论】:

  • 我不明白这怎么可能是 O(V * log(V))。每个 for 循环都是 O(n),函数调用的数量是顶点的数量 - 因此,假设 map 中的插入和搜索是 O(1),总体复杂度是 O(n^2)。但是它们是 O(log(n)),因此总体复杂性与我在主要帖子评论中计算的相同。也许你误会了我?我正在计算整体复杂性 - 用于对所有邻接列表进行排序,而不仅仅是一个。
  • 任意顶点的相邻顶点数为O(V),但平面图中所有顶点的平均相邻顶点数为O(1)。单个顶点可以连接到所有其他顶点,但它们不能全部连接。至少对于尺寸为 V>3 的平面图来说不是。
  • 我明白了,谢谢。所以渐近这个解决方案是可以的,但是它需要坐标,正如我上面描述的那样不好。
猜你喜欢
  • 2011-10-22
  • 2018-06-05
  • 1970-01-01
  • 1970-01-01
  • 2011-10-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-19
相关资源
最近更新 更多