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

目录

  • 一、二叉搜索树的相同判断
  • 二、问题引入
  • 三、举例分析
  • 四、方法探讨
    • 4.1 中序遍历
    • 4.2 层序遍历
    • 4.3 先序遍历
    • 4.4 后序遍历
  • 五、总结
  • 六、代码实现

更新、更全的《数据结构与算法》的更新网站,更有python、go、人工智能教学等着你:https://www.cnblogs.com/nickchen121/p/11407287.html

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

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

二、问题引入

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

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

三、举例分析

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

四、方法探讨

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

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的左右子树;然后以相同的思路进行二分,即可完成构建。

4.4 后序遍历

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

五、总结

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

六、代码实现

# 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")

原文地址:https://www.cnblogs.com/nickchen121/p/11562295.html

时间: 2024-10-08 05:20:50

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

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

目录 一.题意理解 二.求解思路 三.搜索树表示 程序框架搭建 3.1 如何建搜索树 3.2 如何判别 3.3 清空树 更新.更全的<数据结构与算法>的更新网站,更有python.go.人工智能教学等着你:https://www.cnblogs.com/nickchen121/p/11407287.html 一.题意理解 给定一个插入序列就可以唯一确定一颗二叉搜索树.然而,一颗给定的二叉搜索树却可以由多种不同的插入序列得到.例如:按照序列 {2, 1, 3} 和 {2, 3, 1}插入初始为空

给定一颗二叉搜索树,请找出其中的第k大的结点。例如, 5 / \ 3 7 /\ /\ 2 4 6 8 中,按结点数值大小顺序第三个结点的值为4。

/* struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) { } }; */ class Solution { public: TreeNode* KthNode(TreeNode* pRoot, int k) { //中序递归     int count = 0;              if(co

二叉搜索树(python)

# -*- coding: utf-8 -*- class BSTNode(object): def __init__(self, key, value, left=None, right=None): self.key, self.value, self.left, self.right = key, value, left, right class BST(object): def __init__(self, root=None): self.root = root @classmetho

不同的二叉搜索树-python

https://leetcode-cn.com/problems/unique-binary-search-trees/ 思路:对于n个数,1,2,3,4,,,,i,,,n.以i为节点时,i前面的序列作为左子,i右边的作为右子树.左右子树时有顺序的,因此可以忽略具体值得大小,只需要看序列的个数.假设长度为n的序列的有F(n)种构造个数,那么以第i个节点为跟节点的时候个数为前后两个新的序列能够构造的个数的乘积.即F(i,n)=F(i-1)F(n-i),所以总个数为: $F(n) = \sum_{i

Java数据结构之二叉搜索树

Java数据结构之二叉搜索树 1.二叉搜索树组成 二叉搜索树又称为二叉排序树,它或者是一颗空树,或者是一颗具有如下特性的非空二叉树,需要满足一下三个条件: (1)若它的左子树非空,则左子树上所有结点的关键字均小于根结点的关键字: (2)若它的右子树非空,则右子树上所有结点的关键字均大于(可以等于)根结点的关键字. (3)左子树右子树本身又各是一颗二叉搜索树 在算法描述中,均以结点值的比较来代表其关键字的比较,因为若结点的值为类类型时,该类必须实现系统提供的java.lang.comparable

HDU 3791 二叉搜索树 题解

Problem Description 判断两序列是否为同一二叉搜索树序列 Input 开始一个数n,(1<=n<=20) 表示有n个需要判断,n= 0 的时候输入结束. 接下去一行是一个序列,序列长度小于10,包含(0~9)的数字,没有重复数字,根据这个序列可以构造出一颗二叉搜索树. 接下去的n行有n个序列,每个序列格式跟第一个序列一样,请判断这两个序列是否能组成同一颗二叉搜索树. Output 如果序列相同则输出YES,否则输出NO Sample Input 2 567432 543267

二叉搜索树的第k个结点-剑指Offer

二叉搜索树的第k个结点 题目描述 给定一颗二叉搜索树,请找出其中的第k大的结点.例如,5 / \ 3 7 /\ /\ 2 4 6 8 中,按结点数值大小顺序第三个结点的值为4. 思路 对于二叉搜索树,中序遍历的结果是按照顺序来的,我们设置一个变量用来计数,递归的遍历树,如果到了第k个,则把那个数取出来,我在这用的是ArrayList来存储那个结点 还可以在递归方法中直接返回结点,无需用ArrayList跟踪存储,更加简化 代码 import java.util.ArrayList; /* pub

九度OJ刷题——1009:二叉搜索树

题目描述: 判断两序列是否为同一二叉搜索树序列 输入: 开始一个数n,(1<=n<=20) 表示有n个需要判断,n= 0 的时候输入结束.接下去一行是一个序列,序列长度小于10,包含(0~9)的数字,没有重复数字,根据这个序列可以构造出一颗二叉搜索树.接下去的n行有n个序列,每个序列格式跟第一个序列一样,请判断这两个序列是否能组成同一颗二叉搜索树. 输出: 如果序列相同则输出YES,否则输出NO 样例输入: 2 567432 543267 576342 0 样例输出: YES NO 这题我的思

二叉搜索树比较

前言: 二叉搜索树是二叉排序树,左子树比根小,右子树比根大,所以它建树的方式和普通建树的方式稍有不同,每次都要和根节点往下比较而确定位置,然后采用遍历二叉树节点的方式确定两棵树是否完全相等. 言归正传,在牛客网页编译器里运行结果有出入,但是在本地调试是没有问题的,而且检验,也没找到有什么逻辑错,这个问题存疑~~~ 题目描述 判断两序列是否为同一二叉搜索树序列 输入描述: 开始一个数n,(1<=n<=20) 表示有n个需要判断,n= 0 的时候输入结束.接下去一行是一个序列,序列长度小于10,包