
判断二叉树是否是完全的BST
发布日期:2021-05-07 22:02:51
浏览次数:16
分类:精选文章
本文共 4411 字,大约阅读时间需要 14 分钟。
1. 问题描述:判断一棵二叉树是否是完全的BST(Binary Search Tree 二叉搜索树)
二叉查找树(Binary Search Tree),(二叉搜索树或者称为二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。
其中满足二叉搜索树的一个典型的特征是使用中序遍历二叉树的时候得到的序列是一个上升序列
2. 判断二叉树有以下几种方法:
① 从根节点开始遍历二叉树,其中需要使用到递归进行遍历节点,判断根的左右节点的值与根节点的值的大小的比较,其中递归的思路是假如树有左子树那么我们遍历左子树,有右子树那么遍历右子树,左右子树都有那么我们遍历左右子树,为叶子节点的时候直接返回true即可
除了上面的判断之外还不够,还需要判断左子树中最大的节点值是否小于根节点的值,右子树中最小的节点的值是否大于根节点的值
因为有的二叉树是这样的但是它不是二叉搜索树,所以需要加上上面的判断
10 8 11 1 100 2 15
代码如下:
public class Main{ public static void main(String[] args) { TreeNoderoot = new TreeNode (10); TreeNode l = new TreeNode (8); TreeNode r = new TreeNode (11); TreeNode ll = new TreeNode (1); TreeNode lr = new TreeNode (100); TreeNode rl = new TreeNode (2); TreeNode rr = new TreeNode (15); //把树的节点连接成一棵树: 主要是通过节点之间的引用之间的关系来解决 root.left = l; root.right = r; l.left = ll; l.right = lr; r.left = rl; r.right = rr; boolean b1 = isBST(root); boolean b2 = maxOf(root); boolean b3 = minOf(root); System.out.println(b1 && b2 && b3); } private static boolean isBST(TreeNode root) { if(root.left == null && root.right == null) return true; else if(root.left != null) return root.val > root.left.val && isBST(root.left); else if(root.right != null) return root.val < root.right.val && isBST(root.right); else{ return root.val > root.left.val && root.val < root.right.val && isBST(root.left) && isBST(root.right); } } private static boolean minOf(TreeNode root) { if(root == null) { return true; } TreeNode p = root; p = p.right; if(p == null) return true; if(p != null){ while(p.left != null){ p = p.left; } } System.out.println("最小值: " + p.val); return p.val > root.val; } private static boolean maxOf(TreeNode root) { if(root == null) return true; TreeNode p = root; p = p.left; if(p == null) return true; if(p != null){ while(p.right != null){ p = p.right; } } System.out.println("最大值: " + p.val); return p.val < root.val; }}
② 使用典型判断是否是二叉搜索树的办法是使用中序遍历,把中序遍历的结果放入到一个数组中,遍历数组两两比较数组中的元素是否是有序的,假如发现有的不满足条件说明不是完全的BST
代码如下:
import java.util.ArrayList;public class Main { // 中序遍历是否有序 public boolean checkBST(TreeNode root) { if (root == null) return false; ArrayListlist = new ArrayList<>(); inorder(root, list); return checkOrdered(list); } // 递归方式把节点按中序遍历顺序加入到列表中 private void inorder(TreeNode node, ArrayList list) { if (node == null) return; if (node.left != null) { inorder(node.left, list); } list.add(node.val); if (node.right != null) { inorder(node.right, list); } } //遍历列表,前后两两比较,如果逆序,返回false private boolean checkOrdered(ArrayList list) { for (int i = 0; i < list.size() - 2; i++) { if (list.get(i) > list.get(i + 1)) return false; } return true; }}
③ 在中序遍历的基础上我们可以使用全局变量来记录遍历到的根节点的最大值与左子树的值进行比较,其中递归的时候需要更新根节点的最大值,对于右子树的判断也是一样的,因为左右子树是对称的
代码如下:
import org.junit.Test;/*public class TreeNode { int data = 0; TreeNode left = null; TreeNode right = null; public TreeNode(int data) { this.data = data; }}*/public class Main { public boolean checkBST(TreeNoderoot) { if (root == null) return true; //检查左子树,如果左子非bst立即返回false boolean leftIsBST = checkBST(root.left); if (!leftIsBST) return false; //根的值小于等于左子树的最大值,返回false if (root.val <= preValue) { return false; } //更新最后访问的值,检查右子树 preValue = root.val; return checkBST(root.right); } private int preValue = Integer.MIN_VALUE; @Test public void test1() { TreeNode root = new TreeNode(9); root.left = new TreeNode(2); root.right = new TreeNode(20); root.left.left = new TreeNode(1); root.left.right = new TreeNode(3); root.right.left = new TreeNode(15); root.right.right = new TreeNode(28); // root.right.left.left = new TreeNode(8); root.right.left.left = new TreeNode(10); root.right.left.right = new TreeNode(16); root.right.right.left = new TreeNode(25); root.right.right.right = new TreeNode(29); } @Test public void test2() { TreeNode root = new TreeNode(4); root.left = new TreeNode(2); root.right = new TreeNode(6); root.left.left = new TreeNode(1); root.left.right = new TreeNode(5); root.right.left = new TreeNode(3); }}
发表评论
最新留言
第一次来,支持一个
[***.219.124.196]2025年04月02日 18时25分14秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
java 重写(override)和重载(overload)区别
2019-03-04
java 多态类型转换
2019-03-04
常用正则表达式
2019-03-04
XML:采用XHTML和CSS设计可重用可换肤的WEB站点
2019-03-04
Tomcat6中web项目部署路径webapps和wtpwebapps的区别
2019-03-04
Java判断字符串是否为金额
2019-03-04
软件架构-zookeeper快速入门
2019-03-04
angr学习笔记(7)(malloc地址单元符号化)
2019-03-04
「CF149D」括号涂色 区间DP好题
2019-03-04
树状数组 模板总结
2019-03-04
「NOI2015」程序自动分析 并查集题解
2019-03-04
[JSOI2008]Blue Mary的战役地图 Hash题解
2019-03-04
结构型设计在工作中的一些经验总结
2019-03-04
如何提升员工体验 助力企业业务增长?这个棘手的问题终于被解决了!
2019-03-04
2020 AI 产业图谱启动,勾勒中国 AI 技术与行业生态
2019-03-04
Netty4服务端入门代码示例
2019-03-04
MyBatis自定义类型转换器
2019-03-04
Python:面向对象
2019-03-04
Spring源码:prepareBeanFactory(beanFactory);方法
2019-03-04
AcWing 828. 模拟栈
2019-03-04