构造给定根的树

时间:2018-08-30 01:45:28

标签: python

例如[13,11], [13,8], [6, 8], [3, 6] 根是1

寻找一种Python方法将一棵树构造成一个字典,这样我们便有了{13: [11, 8], 11: [], 3: [], 6: [3], 8: [6]}

因为我知道根,所以我要采用的方法是用13循环遍历条目,然后将它们连接起来,然后将这些条目视为根,依此类推。

请注意,没有订购。为了区分它们,我知道根(一些数字)并且可以从那里确定。

有更好的方法吗?

5 个答案:

答案 0 :(得分:1)

通过使用set跟踪哪些元素已添加到字典中,我们可以在O(n)时间内解决此问题。一般的想法是循环遍历节点,检查当前是否在图中有一个节点,如果有,在添加到字典中时我们知道它是父节点。

from collections import defaultdict

class MyTree:
    def __init__(self, data):
        self.data = defaultdict(list)
        self.seen = set()

        for node in data:
            self.add_node(node)

        for el in self.seen:
            if el not in self.data:
                self.data[el] = []

    def add_node(self, el):
        x, y = el

        if y in self.seen:
            self.data[y].append(x)
        else:
            self.data[x].append(y)

        self.seen.update(el)

实际情况:

arr = [[1,2], [1,8], [5, 8], [3, 5]]

x = MyTree(arr)
print(x.data)

defaultdict(<class 'list'>, {1: [2, 8], 8: [5], 5: [3], 2: [], 3: []})

答案 1 :(得分:1)

我能想到的最pythonic的方式,也是最快的一种:

def dfs(es, s):
    graph = {}
    for x, y in es:
        graph.setdefault(x, set()).add(y)
        graph.setdefault(y, set()).add(x)

    tree, stack = {}, [s]
    while stack:
        parent = stack.pop()
        children = graph[parent] - tree.keys()
        tree[parent] = list(children)
        stack.extend(children)
    return tree

edges = [[1, 2], [5, 8], [1, 8], [3, 5]]
print(dfs(edges, 1))

输出

{8: [5], 1: [8, 2], 2: [], 3: [], 5: [3]}

以上方法在图O(N + E)的大小上是线性的,其中N是节点数,E是边数。一种较简单的方法,尽管速度较慢:

egdes = [[1, 2], [1, 8], [5, 8], [3, 5]]
tree = {}
sources = {1}


while sources:
    parent = sources.pop()
    children = [t for s, t in egdes if (s == parent and t not in tree)] + \
               [s for s, t in egdes if (t == parent and s not in tree)]
    tree[parent] = children
    sources.update(children)

print(tree)

输出

{8: [5], 1: [2, 8], 2: [], 3: [], 5: [3]}

一种更快的方法是删除已经看到的边缘:

while sources:
    parent = sources.pop()
    children = [y if x == parent else x for x, y in edges if parent in (x, y)]
    edges = [edge for edge in edges if parent not in edge]
    tree[parent] = children
    sources.update(children)

输出

{8: [5], 1: [2, 8], 2: [], 3: [], 5: [3]}

答案 2 :(得分:0)

一种递归方法:

# view
<%= react_component 'Policies.Policies' %>

# component
# app/javascripts/components/policies/Policies.js
import React from 'react'
import PropTypes from 'prop-types'

export default class Policies extends React.Component {
  render() {
    <div>
      <h1>I'm watching you</h1>
    <div>
  }
}

这将输出:

Error: Cannot find module './Policies'.
ReferenceError: Policies is not defined
Uncaught Error: Cannot find component: 'Policies.Policies'. Make sure your component is available to render.

答案 3 :(得分:0)

您可以使用广度优先搜索:

import collections
data = [[1,2], [1,8], [5, 8], [3, 5]]
def bfs(d, _start = lambda x:x[0][0]):
  _queue, _result, _seen = collections.deque([_start(d)]), collections.defaultdict(list), []
  while _queue:
    v = _queue.popleft()
    r = [i[0] if i[-1] == v else i[-1] for i in d if v in i]
    _r = [i for i in r if i not in _seen]
    _result[v].extend(_r)
    _queue.extend(_r)
    _seen.extend(_r+[v])
  return _result

print(bfs(data))

输出:

defaultdict(<class 'list'>, {1: [2, 8], 8: [5], 5: [3], 2: [], 3: []})

答案 4 :(得分:-1)

d = [[1,2], [1,8], [5, 8], [3, 5]]
def t(d, r):
    o = {r: []}
    while d:
        e = d.pop(0)
        if e[1] in o:
            e = e[::-1]
        if e[0] in o:
            o[e[0]].append(e[1])
            o[e[1]] = []
        else:
            d.append(e)
    return o
print(t(d, 1))

这将输出:

{1: [2, 8], 2: [], 8: [5], 5: [3], 3: []}