小白专场-是否同一颗二叉搜索树-python语言实现

更新、更全的《数据结构与算法》的更新网站,更有python、go、人工智能教学等着你:http://www.javashuo.com/article/p-zfinzipt-hh.htmlnode

1、二叉搜索树的相同判断

二叉搜索树是一种特殊的二叉树,在必定程度上是基于二分查找思想产生的,在它的任何一个节点node处,node的左子树中的全部元素都比node自己的数值要小,而node的右子树中的全部元素都比node自己要大。python

2、问题引入

与普通的二叉树不一样,任意给一串不重复的数字,就能够肯定一棵二叉搜索树,例如:当给定序列12,5,11,17,16,19,18时,能够肯定的二叉搜索树以下:算法

本质上,因为二叉搜索树的节点左右按大小分界的性质,肯定一棵二叉搜索树最重要的仍是序列中数字出现的次序,一个小小的调换就可能致使二叉搜索树改变,所以,有时候咱们须要找到一些方法来确认两个序列所对应的二叉搜索树是否为同一棵二叉搜索树。数据结构

3、举例分析

咱们以最简单的例子,由1,2,3构成的6种序列,及其对应的二叉搜索树、先序、中序、后序、层序遍历结果分别以下:app

4、方法探讨

咱们可能会天然地想到用遍历对两颗二叉搜索树进行比较,经常使用的遍历方法:
先序遍历、中序遍历、后序遍历、层序遍历
下面咱们将分点探讨他们的效果。函数

4.1 中序遍历

中序遍历老是先遍历当前节点node的左子节点,而后遍历自身元素、以后遍历右子节点。于是,在二叉搜索树中,中序遍历的结果老是全部元素的升序排列(如上表中标红的一行所示);换句话说,中序遍历结果是不能帮助咱们判断两个序列是否对应同一棵二叉搜索树的。网站

4.2 层序遍历

  1. 因为二叉搜索树的构建方式与元素在每一层的分布密切相关,对于出现元素集合彻底相同的两个不一样的序列,它们各自所对应的二叉搜索树若是在某一层开始出现的元素不相同,那么它们不是同一棵二叉搜索树。
  2. 这也能够由递归的思想来理解,对于特定的某一层来讲,因为前一层已经肯定,那么将序列中剩下的元素按前后顺序插入树中的合适位置时,其位置也就自动被惟一肯定了,每一个元素是否能在某一层出现以及在该元素某一层出现的位置是肯定死了的,彻底由上一层的元素来决定,不存在其余的位置来放置它。
  3. 再者,若是给咱们了一棵二叉搜索树的层序遍历结果,咱们会发现是能够还原出一整棵二叉搜索树的,这与普通二叉树有些区别。
    所以能够由层序遍历结果完成咱们的判断。

4.3 先序遍历

根据一个先序遍历结果(不妨仍以上面的那棵二叉搜索树为例,其先序遍历结果是12,5,11,17,16,19,18),从根节点12开始,根据与12的大小关系,12后面的5和11确定在左子树中,而17,16,19,18确定在12的右子树中;在5和11中,根据顺序,5应做为12左子树的根节点,而后11比5大,因此11是5的右子节点,这样左子树判断完毕;在左子树17,16,19,18中,17是根节点,16是17的左子节点、19和18是17的右子树,其中19是17的右子节点,18是19的左子节点。这样咱们就完成了整个二叉搜索树的构建。人工智能

整合一下,咱们看到,在二叉搜索树的概念下,先序遍历的结果能够逐步“二分”,分红比node小和比node大的两部分,分别构成node的左右子树;而后以相同的思路进行二分,便可完成构建。code

4.4 后序遍历

后序遍历与先序遍历本质上同样,只是在逻辑上进行了彻底翻转(注意不是简单的序列翻转),思路和先序遍历基本相同,仍然须要递归分组,只是须要从遍历结果的最后一个元素开始反向构建。

5、总结

由前述分析讨论可见,在二叉搜索树的概念之下,中序遍历损失的信息量是最大的,但因为它获得的结果的升序特性,这是咱们能够用它来判断一棵二叉树是不是二叉搜索树,这是其余几种遍历没法作到的,这也表示了中序遍历与二叉搜索树结合得很紧密。
而层序、先序、后序遍历均可以用来判断两个给定序列是否为同一棵二叉搜索树(这里以先序遍历结果实现以下)。

6、代码实现

# python语言实现

# Judge the same binary search tree

# 因为二叉搜索树不一样于二叉树,仅根据二叉搜索树的先序遍历结果就能断定二叉树的惟一形状;
# 所以咱们能够经过比较两个二叉搜索树的先序遍历结果来判断他们是否为同一个二叉搜索树;


class node:
    def __init__(self, elem=None, lchild=None, rchild=None):
        self.elem = elem
        self.lchild = lchild
        self.rchild = rchild


class tree:
    def __init__(self, root=node()):
        self.root = root


def bi_search_tree_establish(List):  # 根据输入的列表创建二叉搜索树
    if List:
        mytree = tree(node(List[0]))
        for i in range(1, len(List)):
            temp_node = mytree.root
            while temp_node:
                if List[i] < temp_node.elem:
                    if temp_node.lchild:
                        temp_node = temp_node.lchild
                    else:
                        temp_node.lchild = node(List[i])
                        break
                else:
                    if temp_node.rchild:
                        temp_node = temp_node.rchild
                    else:
                        temp_node.rchild = node(List[i])
                        break
        return mytree
    else:
        return None


def preorder_probing(now_node, pre_L):  # 先序遍历——递归实现
    # print(now_node.elem)
    pre_L.append(now_node.elem)
    if now_node.lchild:
        preorder_probing(now_node.lchild, pre_L)
    if now_node.rchild:
        preorder_probing(now_node.rchild, pre_L)


def cmp(a, b):  # 比较序列函数,Python3的经常使用函数库里已经没有cmp函数了
    leng = len(a)
    if leng == len(b):
        for i in range(0, leng):
            if a[i] != b[i]:
                # print("False")
                return -1
        # print("True")
        return 0
    else:
        # print("False")
        return -1


if __name__ == "__main__":

    N = int(input())  # 输入n表示须要检测的组数
    S_List = [int(i) for i in input()]  # 输入一个二叉搜索树序列做为标准,与下面的进行比较
    S_Tree = bi_search_tree_establish(S_List)  # 构建标准二叉搜索树

    if S_Tree:
        S_pre_list = []
        preorder_probing(S_Tree.root, S_pre_list)

        for i in range(0, N):
            List = [int(i) for i in input()]  # 输入待比较的二叉搜索树序列
            MyTree = bi_search_tree_establish(List)  # 构建待比较二叉搜索树
            if MyTree:
                pre_list = []
                preorder_probing(MyTree.root, pre_list)

                if cmp(S_pre_list, pre_list) == 0:
                    print("YES")
                else:
                    print("NO")
相关文章
相关标签/搜索