查了一圈网上现有的资料,基本都是“天下文章一大抄”或者过时、甚至无法运行的代码,也没有讲明原理,代码质量烂得一比,怒而亲自动手。
思路很简单:
- 初始化N个树节点,每次随机从中选出一个父节点和子节点,随机决定子节点作为父节点的左叶或右叶;
- 特别的,使用并查集来避免出现构建回环的情况;(并查集的相关知识请参考《算法4》)
- 考虑到每个节点最多只会有一个入度和两个出度,因此可以添加父、子节点的待选列表,解决随机碰撞影响效率的问题。
给出对树节点的结构定义:
class TreeNode:
def __init__(self, value=None):
self.v = value
self.left, self.right = None, None
self.father = None
上述思路的具体实现,请参考以下代码及详实的注释来理解:
def build_random_tree(n):
"""
构建一棵随机树
:param n: 树的节点总数
:return: 所有节点的list(根节点为list的第一个元素)
"""
assert n > 1
import random as r
all_nodes = [[0, TreeNode(i + 1)] for i in range(n)