判定一棵二叉树是否是二叉搜索树
问题
解法1:暴力搜索
- 结点node的左子树所有结点的值都小于node的值。
- 结点node的右子树所有结点的值都大于node的值。
- 结点node的左右子树同样都必须是二叉搜索树。
10/ \5 15 -------- binary tree (1)/ \6 20
那么,根据二叉搜索树的定义,可以想到一种暴力搜索的方法来判定二叉树是否为二叉搜索树。
假定当前结点值为k。则对于二叉树中每个结点,其左子树所有结点的值必须都小于k,其右子树所有结点的值都必须大于k。
暴力搜索算法代码如下,虽然效率不高,但是它确实能够完成工作。该解法最坏情况复杂度为O(n^2),n为结点数目。(当所有结点都在一边的时候出现最坏情况)
/*判断左子树的结点值是否都小于val*/
bool isSubTreeLessThan(BinaryTree *p, int val)
{if (!p) return true;return (p->data < val &&isSubTreeLessThan(p->left, val) &&isSubTreeLessThan(p->right, val));
}/*判断右子树的结点值是否都大于val*/
bool isSubTreeGreaterThan(BinaryTree *p, int val)
{if (!p) return true;return (p->data > val &&isSubTreeGreaterThan(p->left, val) &&isSubTreeGreaterThan(p->right, val));
}/*判定二叉树是否是二叉搜索树*/
bool isBSTBruteForce(BinaryTree *p)
{if (!p) return true;return isSubTreeLessThan(p->left, p->data) &&isSubTreeGreaterThan(p->right, p->data) &&isBSTBruteForce(p->left) &&isBSTBruteForce(p->right);
}
一个类似的解法是:对于结点node,判断其左子树最大值是否大于node的值,如果是,则该二叉树不是二叉搜索树。如果不是,则接着判断右子树最小值是否小于或等于node的值,如果是,则不是二叉搜索树。如果不是则接着递归判断左右子树是否是二叉搜索树。(代码中的maxValue和minValue函数功能分别是返回二叉树中的最大值和最小值,这里假定二叉树为二叉搜索树,实际返回的不一定是最大值和最小值)
int isBST(struct node* node)
{ if (node==NULL) return(true);//如果左子树最大值>=当前node的值,则返回falseif (node->left!=NULL && maxValue(node->left) >= node->data) return(false);// 如果右子树最小值<=当前node的值,返回falseif (node->right!=NULL && minValue(node->right) <= node->data) return(false);// 如果左子树或者右子树不是BST,返回falseif (!isBST(node->left) || !isBST(node->right)) return(false);// 通过所有测试,返回truereturn(true);
}
解法2:更好的解法
int isBST2(struct node* node)
{return(isBSTUtil(node, INT_MIN, INT_MAX));
}
/*
给定的二叉树是BST则返回true,且它的值 >min 以及 < max.
*/
int isBSTUtil(struct node* node, int min, int max)
{if (node==NULL) return(true);// 如果不满足min和max约束,返回falseif (node->data<=min || node->data>=max) return(false);// 递归判断左右子树是否满足min和max约束条件returnisBSTUtil(node->left, min, node->data) &&isBSTUtil(node->right, node->data, max));
}
由于该算法只需要访问每个结点1次,因此时间复杂度为O(n),比解法1效率高很多。
解法3:中序遍历算法
bool isBSTInOrder(BinaryTree *root)
{int prev = INT_MIN;return isBSTInOrderHelper(root, prev);
}
/*该函数判断二叉树p是否是一棵二叉搜索树,且其结点值都大于prev*/
bool isBSTInOrderHelper(BinaryTree *p, int& prev)
{if (!p) return true;if (isBSTInOrderHelper(p->left, prev)) { // 如果左子树是二叉搜索树,且结点值都大于previf (p->data > prev) { //判断当前结点值是否大于prev,因为此时prev已经设置为已经中序遍历过的结点的最大值。prev = p->data;return isBSTInOrderHelper(p->right, prev); //若结点值大于prev,则设置prev为当前结点值,并判断右子树是否二叉搜索树且结点值都大于prev。} else {return false;}}else {return false;}
}
判定一棵二叉树是否是二叉搜索树相关推荐
- 数据结构---判断一棵树是否是二叉搜索树
数据结构-判断一棵树是否是二叉搜索树 代码: #pragma once #define N 100 #define elemType BTree* #include<stdlib.h> t ...
- 判断二叉树是否为二叉搜索树
1.题目 给定一棵二叉树的根节点,判断其是否为二叉搜索树. 2.分析 二叉搜索树:每一棵子树的根节点,左子树的值比根节点的值小,右子树的值比根节点的值大. 经典的二叉搜索树是没有重复值的.如果要放重复 ...
- C语言判断二叉树是否为二叉搜索树(附完整源码)
C语言判断二叉树是否为二叉搜索树 C语言判断二叉树是否为二叉搜索树完整源码(定义,实现,main函数测试) C语言判断二叉树是否为二叉搜索树完整源码(定义,实现,main函数测试) #include ...
- 按照层次序列创建二叉树,并判断二叉树是否为二叉搜索树
首先定义树节点的数据结构,如下: struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; }; 两个函数,用 ...
- 二叉树查找python_二叉搜索树的python实现
介绍 二叉查找树(Binary Search Tree),也称为二叉搜索树.有序二叉树或排序二叉树,是指一棵空树或者具有下列性质的二叉树: 若任意节点的左子树不空,则左子树上所有节点的值均小于它的根节 ...
- c++判断二叉树是否为二叉搜索树_原创 | 好端端的数据结构,为什么叫它SB树呢?...
点击上方蓝字,关注并星标,和我一起学技术. 大家好,今天给大家介绍一个很厉害的数据结构,它的名字就很厉害,叫SB树,业内大佬往往叫做傻叉树.这个真不是我框你们,而是它的英文缩写就叫SBT. SBT其实 ...
- 4-2-6 二叉树及其遍历 / 二叉搜索树 / 完全二叉树 完全二叉搜索树 (30 分)
一个无重复的非负整数序列,必定对应唯一的一棵形状为完全二叉树的二叉搜索树.本题就要求你输出这棵树的层序遍历序列. 输入格式: 首先第一行给出一个正整数 N(≤1000),随后第二行给出 N 个不重复的 ...
- C++初阶学习————二叉树进阶(二叉搜索树)
二叉树进阶 二叉搜索树的概念 二叉搜索树的操作 基本框架 二叉搜索树的插入 二叉搜索树的查找 二叉搜索树的删除 整体代码 循环写法 递归写法 二叉搜索树的应用 二叉搜索树的性能分析 前面的文章介绍过二 ...
- 二叉树OJ(一)二叉树的最大深度 二叉搜索树与双向链表 对称的二叉树
二叉树的最大深度 二叉树中和为某一值的路径(一) 二叉搜索树与双向链表 对称的二叉树 二叉树的最大深度 描述 求给定二叉树的最大深度, 深度是指树的根节点到任一叶子节点路径上节点的数量. 最大深度是所 ...
最新文章
- svn命令行使用说明
- HDU 2612 Find a way
- 猫咪藏在哪个房间python作业_python练习题之 猫2
- 【面向对象】面向对象程序设计测试题7-对象之间的has-a/many关系测试题
- html5 开发工具_前端HTML5开发工具有哪些呢?
- 各浏览器中的鼠标滚轮事件处理
- 【分享】伙伴们!关注公众号要慎重!这半年我取关了很多,这几个留下了!真心推荐给你!...
- 常用的HTML5和CSS3标签及用法(入门篇)
- python logger.debug_python处理logger日志
- 从execl表中随机抽取几行数据
- nodejs websocket 聊天应用
- Git 修改历史 commit 提交信息
- JAVA房屋租赁管理系统计算机毕业设计Mybatis+系统+数据库+调试部署
- NLP专题直播 | Transformer, BERT, ALBERT, XLNet全面解析(ALBERT第一作者亲自讲解)
- #图书管理系统的设计与实现#
- Intellij IDEA的安装及使用介绍
- 法国童话故事《小王子》读后感
- 高位在前低位在后是啥意思_深度被套后应该如何补仓?终于有人把它讲明白了,精髓都在这里,学会了被套将与你永远无缘...
- 利用matlab绘制系统开环幅频渐进特性曲线(附详细注释)
- 今日头条的文章推荐机制是什么?
热门文章
- Prompt Engineering 入门(一)
- 【Go语言实战】13. Go语言context标准库(下)
- 统计学-基于R (第四版) 贾俊平编著 第二章: 数据可视化 2.1, 2.2 习题答案 【自用】
- 互联网早报:滴滴正式启动造车,滴滴副总裁、小桔车服总经理杨峻负责
- 解决以Error: GlobalConfigUtils setMetaData Fail ! 为基础的嵌套问题(包括common troller,commonservice等问题)
- 【经验分享】桥接网络无法联网、开发板挂载根文件系统问题解决
- vs2019如何关闭自动更新
- 铁路计算机应用期刊级别,铁路单位评审高级职称可以发表哪些期刊呢?
- nps+Proxifier搭建socks5代理隧道进行内网穿透
- 【简单3d网络游戏制作】——基于Unity