给定一个整数n, 如何构建出以 1 ... n 为节点组成的所有二叉搜索树?

问题描述

给定一个整数 n,求以 1 … n 为节点组成的二叉搜索树有多少种?

程序代码

输入: 3
输出: 5
解释:
给定 n = 3, 一共有 5 种不同结构的二叉搜索树:

   1         3     3      2      1
    \       /     /      / \      \
     3     2     1      1   3      2
    /     /       \                 \
   2     1         2                 3
class BinaryTreeNode:
    def __init__(self, data):
        self.data = data
        self.left_child = None
        self.right_child = None


def constructBinaryTree(inorder_traversal, left_index, right_index):
    if left_index > right_index:  # 二叉树为空树,直接返回空根节点
        return [BinaryTreeNode(None)]

    if left_index == right_index:  # 二叉树仅含一个节点必然为二叉搜索树
        root = BinaryTreeNode(inorder_traversal[left_index])
        return [root]

    root_node_list = []  # 当前中序序列对应的所有二叉树的根节点表
    for i in range(left_index, right_index + 1):
        left_sub = constructBinaryTree(inorder_traversal, left_index, i - 1)  # 构造所有左子树
        right_sub = constructBinaryTree(inorder_traversal, i + 1, right_index)  # 构造所有右子树
        for j in range(len(left_sub)):
            for k in range(len(right_sub)):  # 由构造出的左右子树合成当前中序序列对应的所有二叉树
                root = BinaryTreeNode(inorder_traversal[i])
                root.left_child = left_sub[j]
                root.right_child = right_sub[k]
                root_node_list.append(root)

    return root_node_list


def isBST(root):  # 判断二叉树是否为二叉搜索树
    def helper(node, lower, upper):
        if not node or not node.data:
            return True

        if lower < node.data < upper:
            return helper(node.left_child, lower, node.data) and helper(node.right_child, node.data, upper)
        else:
            return False

    return helper(root, float('-inf'), float('inf'))


def midTraverse(root):
    """
    中序遍历
    """
    if root is None:
        return
    midTraverse(root.left_child)
    print(root.data,
          root.left_child.data if root.left_child else None,
          root.right_child.data if root.left_child else None)
    midTraverse(root.right_child)


def main():
    n = 4
    inorder_traversal = [1, 2, 3, 4]
    root_list = constructBinaryTree(inorder_traversal, 0, len(inorder_traversal) - 1)

    for i in range(len(root_list)):
        result = isBST(root_list[i])
        if result is False:
            print("错误,构造出的二叉树中存在不为二叉搜索树的二叉树")
            exit(-1)

    tree_num = 1
    for m in root_list:
        midTraverse(m)
        print("-" * 20 + f"{tree_num}")
        tree_num += 1
    print(f"对应的二叉树共有{len(root_list)}棵,它们均为二叉搜索树")


main()

输出

输出为:

None None None
1 None 2
None None None
2 None 3
None None None
3 None 4
4 None None
--------------------1
None None None
1 None 2
None None None
2 None 4
3 None None
4 3 None
None None None
--------------------2
None None None
1 None 3
2 None None
3 2 4
4 None None
--------------------3
None None None
1 None 4
None None None
2 None 3
3 None None
4 2 None
None None None
--------------------4
None None None
1 None 4
2 None None
3 2 None
None None None
4 3 None
None None None
--------------------5
1 None None
2 1 3
None None None
3 None 4
4 None None
--------------------6
1 None None
2 1 4
3 None None
4 3 None
None None None
--------------------7
None None None
1 None 2
2 None None
3 1 4
4 None None
--------------------8
1 None None
2 1 None
None None None
3 2 4
4 None None
--------------------9
None None None
1 None 2
None None None
2 None 3
3 None None
4 1 None
None None None
--------------------10
None None None
1 None 3
2 None None
3 2 None
None None None
4 1 None
None None None
--------------------11
1 None None
2 1 3
3 None None
4 2 None
None None None
--------------------12
None None None
1 None 2
2 None None
3 1 None
None None None
4 3 None
None None None
--------------------13
1 None None
2 1 None
None None None
3 2 None
None None None
4 3 None
None None None
--------------------14
对应的二叉树共有14,它们均为二叉搜索树

翻译来源

https://www.zhihu.com/question/327882886
@naturerun

猜你喜欢

转载自blog.csdn.net/weixin_41845533/article/details/91044886
今日推荐