如何在线性时间内反转图形?

时间:2013-04-23 00:23:32

标签: algorithm data-structures graph dijkstra

我知道有两种表示图形的方法:一种是使用矩阵,另一种是使用列表。

如果我使用矩阵,我必须翻转矩阵中的所有位。这不是需要O(V ^ 2)时间吗?

如果我使用列表,我不是必须逐个遍历每个列表,并创建一个新集合吗?这似乎需要O(V + E)时间是线性的。我是对的吗?

所以,我在这里有另一个问题。例如,考虑我在我的图形上使用Dijkstra算法(矩阵或列表),并且我们使用优先级队列作为场景后面的数据结构。图表表示与数据结构的使用有关系吗?它会影响算法的性能吗?

假设我使用Dijkstra算法的表示和优先级队列列表,Dijkstra的矩阵和使用优先级队列之间会有区别吗?

我猜它只与makeQueue操作有关?或者他们根本没有什么不同?

4 个答案:

答案 0 :(得分:22)

反转有向图的邻接列表可以在线性时间内完成。我们只遍历图表一次。复杂度的顺序为O(| V | + | E |)。

  1. 维护Adjaceny列表的HashMap,其中键是顶点标签,值是关键顶点的相邻顶点的ArrayList。
  2. 要进行反转,请创建相同类型的新HashMap。扫描原始哈希映射,并为您遇到的每个密钥遍历相应的列表。
  3. 对于值列表中找到的每个顶点,在新的hashMap中添加一个键,将原始HashMap的键作为一个条目放在ArrayList中,对应于新HashMap中的新键。
  4. public static HashMap<Character,ArrayList <Character>> getReversedAdjLists(RGraph g)
    {
        HashMap <Character, ArrayList<Character>> revAdjListMap = new HashMap <Character, ArrayList<Character>>();
        Set <Character> oldLabelSet = g.adjListMap.keySet();
    
        for(char oldLabel:oldLabelSet)
        {
            ArrayList<Character> oldLabelList = g.adjListMap.get(oldLabel);
    
            for (char newLabel : oldLabelList)
            {
                ArrayList<Character> newLabelList = revAdjListMap.get(newLabel);
    
                if (newLabelList == null)
                {
                    newLabelList = new ArrayList<Character>();
                    newLabelList.add(oldLabel);
                }
                else if ( ! newLabelList.contains(oldLabel))
                {
                    newLabelList.add(oldLabel);
                }
    
                revAdjListMap.put(newLabel, newLabelList);
            }
        }
    
        return revAdjListMap;
    }
    

答案 1 :(得分:0)

我认为通过遍历列表来反转图形需要O(V 2 ),因为对于每个顶点,您必须添加或删除(V-1)边。

对于Dijkstra的算法,据我所知,如果将图表表示为矩阵或列表,则算法采用O(V 2 ),但其他一些数据结构更快。最快的是Fibonacci堆,它给出了O(E + VlogV)。

答案 2 :(得分:0)

G = {"A":["B", "C","D"],"B":["C", "E"], "C":["D", "E"],"D":[],"E":["D"] }
res ={}
for k in G.keys():
    for val in G[k]:
        if val not in res.keys():
            res[val] = [k]
        else:
            res[val].append(k)

print(res)

答案 3 :(得分:0)

由于我看到一些评论询问就地图转置(反转)的问题,因此这是我的版本。请注意,这仅适用于DAG。欢迎反馈和提出改进建议

def transpose(G):
    """
    Return the transpose of a directed graph i.e. all the edges are reversed (In Place)
    """
    #note this is not a standard lib function afaik and you would have to 
    #implement topological sort but that should be easy
    topsort = topological_sort(G) 
    topsort.reverse() # we want to process starting from sink node
    for v in topsort:
        for node in G[v]:
            G[node].append(v)
        #  remove all older members of the vertex 'v'  
        G[v] = []
    print(G)