简体   繁体   English

枚举所有完整(标记)二叉树

[英]Enumerate all full (labeled) binary tree

I'm searching a practical algorithm for enumerating all full labeled binary tree.我正在寻找一种实用的算法来枚举所有完整标记的二叉树。

A full binary tree is a tree where all internal nodes has a degree 3, the leaves has degree 1 and the root has a degree 2.满二叉树是所有内部节点的度数为 3,叶子的度数为 1,根的度数为 2 的树。

A labeled tree is a tree where all leaves has a unique label.标记树是所有叶子都有唯一标签的树。

Example:例子:

    *
    |\
    | \
    *  *
   /|  |\
  / |  | \
 T  C  D  F

From comments, it is clear that the question is to enumerate rooted unordered labelled full binary trees.从评论中,很明显问题是枚举有根无序标记的全二叉树。 As explained in this paper , the number of such trees with n labels is (2n-3)!!本文所述,具有n标签的此类树的数量为(2n-3)!! where !!在哪里!! is the double factorial function .双阶乘函数

The following python program is based on the recursive proof in the referenced paper;以下python程序基于参考论文中的递归证明; I think the code is straight-forward enough that it will pass as an explanation of the algorithm:我认为代码很简单,可以作为对算法的解释:

# A very simple representation for Nodes. Leaves are anything which is not a Node.
class Node(object):
  def __init__(self, left, right):
    self.left = left
    self.right = right

  def __repr__(self):
    return '(%s %s)' % (self.left, self.right)

# Given a tree and a label, yields every possible augmentation of the tree by
# adding a new node with the label as a child "above" some existing Node or Leaf.
def add_leaf(tree, label):
  yield Node(label, tree)
  if isinstance(tree, Node):
    for left in add_leaf(tree.left, label):
      yield Node(left, tree.right)
    for right in add_leaf(tree.right, label):
      yield Node(tree.left, right)

# Given a list of labels, yield each rooted, unordered full binary tree with
# the specified labels.
def enum_unordered(labels):
  if len(labels) == 1:
    yield labels[0]
  else:
    for tree in enum_unordered(labels[1:]):
      for new_tree in add_leaf(tree, labels[0]):
        yield new_tree

For n == 4 , there are (2*4 - 3)!! == 5!! == 1 * 3 * 5 == 15对于n == 4 ,有(2*4 - 3)!! == 5!! == 1 * 3 * 5 == 15 (2*4 - 3)!! == 5!! == 1 * 3 * 5 == 15 (2*4 - 3)!! == 5!! == 1 * 3 * 5 == 15 trees: (2*4 - 3)!! == 5!! == 1 * 3 * 5 == 15棵树:

>>> for tree in enum_unordered(("a","b","c","d")): print tree
... 
(a (b (c d)))
((a b) (c d))
(b (a (c d)))
(b ((a c) d))
(b (c (a d)))
(a ((b c) d))
((a (b c)) d)
(((a b) c) d)
((b (a c)) d)
((b c) (a d))
(a (c (b d)))
((a c) (b d))
(c (a (b d)))
(c ((a b) d))
(c (b (a d)))

Another possible interpretation of the question was that it sought an enumeration of rooted ordered full binary trees with a specified list of labels.该问题的另一种可能解释是,它寻求枚举具有指定标签列表的有根有序全二叉树。 The number of such trees with n leaves is given by C n-1 , from the Catalan number sequence .这种具有 n 片叶子的树的数量由C n-1 ,来自加泰罗尼亚数列

def enum_ordered(labels):
  if len(labels) == 1:
    yield labels[0]
  else:
    for i in range(1, len(labels)):
      for left in enum_ordered(labels[:i]):
        for right in enum_ordered(labels[i:]):
          yield Node(left, right)

For 5 labels, we have C 5-1 == 14 :对于 5 个标签,我们有C 5-1 == 14

>>> for tree in enum_ordered(("a","b","c","d", "e")): print tree
... 
(a (b (c (d e))))
(a (b ((c d) e)))
(a ((b c) (d e)))
(a ((b (c d)) e))
(a (((b c) d) e))
((a b) (c (d e)))
((a b) ((c d) e))
((a (b c)) (d e))
(((a b) c) (d e))
((a (b (c d))) e)
((a ((b c) d)) e)
(((a b) (c d)) e)
(((a (b c)) d) e)
((((a b) c) d) e)

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

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