繁体   English   中英

删除元组列表中的中间对

[英]Removing Intermediate pairs in a list of tuples

给定一个元组列表,例如

[(0,1), (0,2), (0,3), (1,4), (1,5), (2,6), (6,7), (7,8)]

这形成了一种树,其中 0 有 3 个孩子,1 有 2 个孩子,依此类推。 我们还看到 0 -> 2 -> 6 -> 7 -> 8 创建了这个直分支。 我怎样才能删除所有这样的直分支,以便我以如下输出结束:

[(0,1), (0,8), (0,3), (1,4), (1,5)]

类似地,如果它们是 1 与其子节点之间的节点,则如果该节点本身没有子节点,则直接链接到其子节点。

我将用 Python 代码回答这个问题。

这个想法是首先创建一个邻接列表,其中对于每个节点键,字典都有一个包含节点子节点键的列表。

然后使用后序遍历,将恰好有一个子节点的每个节点从链中取出。

最后,将该邻接列表转换回边列表。

代码:

from collections import defaultdict

# create adjacency list as dict(int, List<int>)
def create_graph(edges):
    adj = defaultdict(list)
    for a, b in edges:
        adj[a].append(b)
    return adj
    
# Perform depth-first traversal to remove nodes
# that have exactly one child
def remove_lonely_nodes(adj, nodeid):
    adj[nodeid] = [remove_lonely_nodes(adj, child) for child in adj[nodeid]]
    if len(adj[nodeid]) == 1:  # skip nodeid
        return adj[nodeid][0]
    return nodeid

def getedges(adj, nodeid):
    return [
        (nodeid, childid) for childid in adj[nodeid]
    ] + [
       edge for id in adj[nodeid] 
            for edge in getedges(adj, id)
    ]

示例运行

edges = [(0,1), (0,2), (0,3), (1,4), (1,5), (2,6), (6,7), (7,8)]
adj = create_graph(edges)
remove_lonely_nodes(adj, 0)  # we assume 0 is the root
edges = getedges(adj, 0)
print(edges)  # [(0, 1), (0, 8), (0, 3), (1, 4), (1, 5)]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM