This is a homework, I have difficulties in thinking of it. Please give me some ideas on recursions and DP solutions. Thanks a lot
generate and print all structurally distinct full binary trees with n leaves in dotted parentheses form, "full" means all internal (non-leaf) nodes have exactly two children.
For example, there are 5 distinct full binary trees with 4 leaves each.
U can use recursion, on i-th step u consider i-th level of tree and u chose which nodes will be present on this level according to constraints: - there is parent on previous level - no single children present (by your definition of "full" tree)
recursion ends when u have exactly N nodes.
In Python you could do this
def gendistinct(n):
leafnode = '(.)'
dp = []
newset = set()
newset.add(leafnode)
dp.append(newset)
for i in range(1,n):
newset = set()
for j in range(i):
for leftchild in dp[j]:
for rightchild in dp[i-j-1]:
newset.add('(' + '.' + leftchild + rightchild + ')')
dp.append(newset)
return dp[-1]
alltrees = gendistinct(4)
for tree in alltrees:
print tree
Another Python example with a different strategy.
This is recursive and uses generators. It is slower than the other implementation here but should use less memory since only one list should ever exist in memory at a time.
#!/usr/bin/env python
import itertools
def all_possible_trees(n):
if n == 1:
yield 'l'
for split in range(1, n):
gen_left = all_possible_trees(split)
gen_right = all_possible_trees(n-split)
for left, right in itertools.product(gen_left, gen_right):
yield [left, right]
if __name__ == '__main__':
import sys
n = int(sys.argv[1])
for thing in all_possible_trees(n):
print(thing)
I don't see an obvious way to do it with recursion, but no doubt there is one.
Rather, I would try a dynamic programming approach.
Note that under your definition of full tree, a tree with n leaves has n-1 internal nodes. Also note that the trees can be generated from smaller trees by joining together at the root two trees with sizes 1 to n-1 leaves on the left with n-1 to 1 leaves on the right.
Note also that the "trees" of various sizes can be stored as dotted parenthesis strings. To build a new tree from these, concatenate ( Left , Right ).
So start with the single tree with 1 leaf (that is, a single node). Build the lists of trees of increasing size up to n. To build the list of k-leaf trees, for each j = 1 to k-1, for each tree of j leaves, for each tree of k-j leaves, concatenate to build the tree (with k leaves) and add to the list.
As you build the n-leaf trees, you can print them out rather than store them.
There are 5*1 + 2*1 + 1*2 + 1*5 = 14 trees with 5 leaves.
There are 14*1 + 5*1 + 2*2 + 1*5 + 1*14 = 42 trees with 6 leaves.
来源:https://stackoverflow.com/questions/12292532/generate-all-structurally-distinct-full-binary-trees-with-n-leaves