小白专场-是否同一颗二叉搜索树-python语言实现
更新、更全的《数据结构与算法》的更新网站,更有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 层序遍历
- 由于二叉搜索树的构建方式与元素在每一层的分布密切相关,对于出现元素集合完全相同的两个不同的序列,它们各自所对应的二叉搜索树如果在某一层开始出现的元素不相同,那么它们不是同一棵二叉搜索树。
- 这也可以由递归的思想来理解,对于特定的某一层来说,由于前一层已经确定,那么将序列中剩下的元素按先后顺序插入树中的合适位置时,其位置也就自动被唯一确定了,每个元素是否能在某一层出现以及在该元素某一层出现的位置是确定死了的,完全由上一层的元素来决定,不存在其他的位置来放置它。
- 再者,如果给我们了一棵二叉搜索树的层序遍历结果,我们会发现是可以还原出一整棵二叉搜索树的,这与普通二叉树有些区别。
因此可以由层序遍历结果完成我们的判断。
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")
小白专场-是否同一颗二叉搜索树-python语言实现的更多相关文章
- 小白专场-是否同一颗二叉搜索树-c语言实现
目录 一.题意理解 二.求解思路 三.搜索树表示 程序框架搭建 3.1 如何建搜索树 3.2 如何判别 3.3 清空树 更新.更全的<数据结构与算法>的更新网站,更有python.go.人 ...
- 二叉搜索树 C语言实现
1.二叉搜索树基本概念 二叉搜索树又称二叉排序树,它或者是一棵空树,或者是一棵具有如下特性的非空二叉树: (1)若它的左子树非空,则左子树上所有结点的关键字均小于根结点的关键字: (2)若它的右子树非 ...
- Leetcode 98 验证二叉搜索树 Python实现
给定一个二叉树,判断其是否是一个有效的二叉搜索树. 假设一个二叉搜索树具有如下特征: 节点的左子树只包含小于当前节点的数. 节点的右子树只包含大于当前节点的数. 所有左子树和右子树自身必须也是二叉搜索 ...
- LeetCode 98. 验证二叉搜索树 | Python
98. 验证二叉搜索树 题目来源:https://leetcode-cn.com/problems/validate-binary-search-tree 题目 给定一个二叉树,判断其是否是一个有效的 ...
- 给定一颗二叉搜索树,请找出其中的第k小的结点。例如, 5 / \ 3 7 /\ /\ 2 4 6 8 中,按结点数值大小顺序第三个结点的值为4。
// ConsoleApplication2.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include "stdafx.h ...
- Convert Sorted Array to Binary Search Tree(将一个有序数组转换成一颗二叉搜索树)
Given an array where elements are sorted in ascending order, convert it to a height balanced BST. Fo ...
- 给定一颗二叉搜索树,请找出其中的第k大的结点。例如, 5 / \ 3 7 /\ /\ 2 4 6 8 中,按结点数值大小顺序第三个结点的值为4。
/* struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; TreeNode(int x) : val(x ...
- leetcode-第10周双周赛-5080-查找两颗二叉搜索树之和
题目描述: 自己的提交: class Solution: def twoSumBSTs(self, root1: TreeNode, root2: TreeNode, target: int) -&g ...
- 二叉搜索树(python)
# -*- coding: utf-8 -*- class BSTNode(object): def __init__(self, key, value, left=None, right=None) ...
随机推荐
- [Spring cloud 一步步实现广告系统] 20. 系统运行测试
系统运行 经过长时间的编码实现,我们的主体模块已经大致完成,因为之前我们都是零散的对各个微服务自行测试,接下来,我们需要将所有的服务模块进行联调测试,Let's do it. 清除测试数据&测 ...
- java io读取性能对比
背景 从最早bio的只支持阻塞的bio(同步阻塞) 到默认阻塞支持非阻塞nio(同步非阻塞+同步阻塞)(此时加入mmap类) 再到aio(异步非阻塞) 虽然这些api改变了调用模式,但真正执行效率上是 ...
- js作用域链和预编译
js引擎运行分为两步,预解析 代码执行 (1)预解析: js引擎会拿js里面所有的var还有 function 提升到当前作用域的最前面 (2)代码执行:按照代码书写的顺序从上往下执行 预解析分为:变 ...
- 【MySql】linux下,设置mysql表名忽略大小写
[障碍再现] 状况描述01: 在LINUX下调一个程序经常报出找不到表,但是我明明是建了表的, 测试的时候,遇到一些问题,从Windows平台访问虚拟机中的Web应用,经常报出找不到表 ...
- NNs(Neural Networks,神经网络)和Polynomial Regression(多项式回归)等价性之思考,以及深度模型可解释性原理研究与案例
1. Main Point 0x1:行文框架 第二章:我们会分别介绍NNs神经网络和PR多项式回归各自的定义和应用场景. 第三章:讨论NNs和PR在数学公式上的等价性,NNs和PR是两个等价的理论方法 ...
- 《Head First 设计模式》笔记
第一章 策略模式 00设计原则:找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码放在一起. 把会变化的部分取出并封装起来,好让其它部分不会受到影响.结果如何?代码变化引起的不经意 ...
- HDU 6315
题意略. 思路:本题的思路总的来说就是暴力 + 剪枝. 我们依然用线段树来维护: 定义结点node{ l , r , minn , contirbute} 分别为某个区间的左右端点,和该区间(b序列) ...
- 从入门到入土的JS 随笔day02 新手向
讲讲自增自减和循环语句及三元一次表达式: 一.自增自减实际上就是按照顺序来解读代码, 例如,a++;代表了a先进行了计算,运算完毕后,才进行增加: ++a呢,则是先进行了自增,值加一后再进行运算: 如 ...
- pickle 都写文件
import pickle mylist=[[1,2,3,4,5,6,7],["abc","xyz","hello"],[1,2,3,4,5 ...
- light 1205 - Palindromic Numbers(数位dp)
题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1205 题解:这题作为一个数位dp,是需要咚咚脑子想想的.这个数位dp方程可能不 ...