二叉树的各类实现判断&二叉树的递归套路

如何判断一颗二叉树是否是搜索二叉树? 

搜索二叉树

每个子树头节点的左孩子比它小,右孩子比它大

经典的搜索二叉树没有重复的数

判断

将二叉树按照中序遍历,判断是否为升序

1、先将整棵树中序遍历再判断是否升序
    //中序遍历
    public static ArrayList<Node> traverse_medium(Node node) {
        if (node == null) {
            return null;
        }

        ArrayList<Node> list = new ArrayList<>();

        traverse_medium(node.left);
        //输出改为存储入集合之中
        list.add(node);
        traverse_medium(node.right);

        return list;
    }

    //判断搜索二叉树
    public static boolean is_bst_one(ArrayList<Node> list) {
        for (int i = 0; i < list.size() - 2; i++) {
            if (list.get(i).value >= list.get(i + 1).value) {//这里认为等于不可行
                return false;
            }
        }
        return true;
    }
2、在中序遍历的过程中判断是否升序
        (1) 使用递归的中序遍历
    //判断搜索二叉树
    public static boolean is_bst_two1(Node node) {
        if (node == null) {
            return true;//认为空二叉树是搜索二叉树
        }

        int preValue = Integer.MIN_VALUE;

        //判断左子树是否为搜索二叉树
        boolean isLeftBst = is_bst_two1(node.left);

        //中序遍历的第二轮,输出改为判断
        //如果左树不是搜索二叉树,那么整棵树一定不是搜索二叉树
        if (!isLeftBst) {
            return false;
        }
        if (node.value > preValue) {
            preValue = node.value;//递归逐层向下找,会最先找到最左侧的节点,逐层向上比较,preValue逐层向上赋值
        } else {//node.value <= preValue,不满足搜索二叉树条件
            return false;
        }

        //在左子树为搜索二叉树的前提下,如果右子树为搜索二叉树,那么整棵树一定都是搜索二叉树
        return is_bst_two1(node.right);
    }
        (2)不使用递归的中序遍历 
    //判断搜索二叉树
    public static boolean is_bst_two2(Node node) {
        if (node == null) {
            return true;//认为空二叉树是搜索二叉树
        }

        int preValue = Integer.MIN_VALUE;

        Stack<Node> stack = new Stack<Node>();
        while (!stack.isEmpty() || node != null) {
            if (node != null) {
                stack.push(node);
                node = node.left;//整个左子树入栈
            } else {
                node = stack.pop();//出栈

                //输出变为比较
                if (node.value <= preValue) {//不满足条件
                    return false;
                } else {//node.value > preValue,满足条件
                    preValue = node.value;//preValue逐层向上
                }

                node = node.right;//如果右节点为null则弹出下一个,如果不为null则将右节点弹入栈
            }
        }
        return true;
    }

如何判断一颗二叉树是否是完全二叉树? 

完全二叉树

二叉树从左向右依次变满(左图为满二叉树,右图为普通的完全二叉树)

          

判断

二叉树按宽度遍历

条件1:如果某一个子树的头节点有右孩子没有左孩子,返回false

条件2:在条件1的前提下,如果有一个节点左右孩子不双全,后续的节点都是叶节点(它右侧的所有节点都没有子节点)

    //判断完全二叉树
    public static boolean isCBT(Node node) {
        if (node == null) {
            return true;//空二叉树认为是完全二叉树
        }

        boolean notBoth = false;//记录是否遇到不双全的节点
        Node left = null;
        Node right = null;

        Queue<Node> queue = new LinkedList<>();
        queue.add(node);

        while (!queue.isEmpty()) {
            Node node0 = queue.poll();

            if ((left == null && right != null)//不满足条件1:左节点null且右节点不为null
                    || (notBoth && (left != null || right != null))) {//不满足条件2:遇到不双全的节点但后面的节点不为叶节点
                return false;
            }
            
            if (node0.left != null) {
                queue.add(node0.left);//先右节点入队列
            }
            if (node0.right != null) {
                queue.add(node0.right);//再左节点入队列
            }

            if (left == null || right == null) {//不双全的节点
                notBoth = true;
            }
        }
        return true;
    }

如何判断一颗二叉树是否是满二叉树? 

满二叉树

相关题目

求二叉树的最大深度或节点个数

已知最大深度为max,则节点个数  N = 2^{^{max}} - 1

二叉树的递归套路判断是否为满二叉树

这里可以先看下面的递归套路再理解如何用套路求是否为满二叉树

递归套路:返回二叉树的最大深度,节点个数

在调用的函数中判断是否满足满二叉树的条件

package binarytree;

public class IsFullBinaryTree {

    public static class Node {
        public int value;
        public Node left;
        public Node right;

        public Node(int data) {
            this.value = data;
        }
    }


    public boolean isFullBinaryTree(Node node) {
        return process(node).nodeNumber == Math.pow(2,process(node).depth) - 1;//nodeNumber是否等于2的depth次方-1
    }

    //所需要的信息:返回二叉树的最大深度,节点个数
    public static class Message {
        public int depth;
        public int nodeNumber;

        public Message(int depth, int nodeNumber) {
            this.depth = depth;
            this.nodeNumber = nodeNumber;
        }
    }


    public Message process(Node node) {
        if (node == null) {
            return null;
        }

        Message leftMessage = process(node.left);
        Message rightMessage = process(node.right);

        int depth = Math.max(leftMessage.depth, rightMessage.depth) + 1;//最大深度要加上当前的节点这一层
        int nodeNumber = leftMessage.nodeNumber + rightMessage.nodeNumber + 1;//节点个数=左子树节点个数+右子树节点个数

        return new Message(depth, nodeNumber);
    }
}

如何判断一颗二叉树是否是平衡二叉树? 

平衡二叉树

左子树与右子树的高度差不超过1

二叉树的递归套路

        问左树要的信息:左树是否是平衡二叉树;左树的高度

        问右树要的信息:右树是否是平衡二叉树;右树的高度

递归函数:返回是否为平衡二叉树,二叉树的深度

package binarytree;

public class IsBalancedBinaryTree {
    public static class Node {
        public int value;
        public Node left;
        public Node right;

        public Node(int data) {
            this.value = data;
        }
    }


    public boolean isBalancedBinaryTree(Node node) {
        return process(node).isBalance;
    }

    //所需要的信息:返回是否为平衡二叉树,二叉树的深度
    public static class Message {
        public boolean isBalance;
        public int depth;

        public Message(boolean isBalanced, int depth) {
            this.isBalance = isBalance;
            this.depth = depth;
        }
    }


    public Message process(Node node) {
        if (node == null) {
            return null;
        }

        Message leftMessage = process(node.left);//左边的信息
        Message rightMessage = process(node.right);//右边的信息

        int depth = Math.max(leftMessage.depth, rightMessage.depth) + 1;//最大深度要加上当前的节点这一层
        boolean isBalanced = leftMessage.isBalance && rightMessage.isBalance
                && (Math.abs(leftMessage.depth - rightMessage.depth) <= 1);
        //左右都为平衡二叉树并且左右子树深度差不超过1

        return new Message(isBalanced, depth);
    }
}

二叉树的递归套路

在文章中判断二叉树是否为完全二叉树/满二叉树/平衡二叉树等等的题型,都可以抽象出一个二叉树的递归套路

递归套路

树型DP问题(树上动态规划)可以用二叉树的递归套路来解

这里用/*  */表示具体需要写的代码

package binarytree;

public class Template {

    //Node类,节点
    public static class Node {
        public int value;
        public Node left;
        public Node right;

        public Node(int data) {
            this.value = data;
        }
    }

    //最终调用的函数,返回最后的结果
    public boolean judgment(Node node) {
        return true;//一般调用process函数获得Message对象,再获取Message对象里的信息
    }

    //Message类,信息
    //所需要的信息
    public static class Message {
        /*
        定义属性
         */

        //定义构造器
        public Message() {

        }
    }

    //具体的遍历过程
    public Message process(Node node){
        if (node == null) {
            return null;
        }
        
        Message leftMessage = process(node.left);//左边的信息
        Message rightMessage = process(node.right);//右边的信息
        
        /*
        具体判断具体分析,根据左右子树的属性获取总的这颗树的属性
         */
        
        //创建Message对象,把获取的属性赋值给新的属性,并返回
        return new Message();
    }
}

二叉树的递归套路解判断是否为搜索二叉树

        问左树要的信息:左树是否为搜索二叉树;左树的最大值(左树max < 当前节点的值)

        问右树要的信息:右树是否为搜索二叉树;右树的最小值(右树min > 当前节点的值)

递归函数:返回是否为搜索二叉树,二叉树的最大值,最小值

package binarytree;

public class IsSearchBinaryTree {

    public static class Node {
        public int value;
        public Node left;
        public Node right;

        public Node(int data) {
            this.value = data;
        }
    }


    public boolean isSearchBinaryTree(Node node) {
        return process(node).isSearch;
    }

    //所需要的信息:返回是否为搜索二叉树,二叉树的最大值,最小值
    public static class Message {
        public boolean isSearch;
        public int max;
        public int min;

        public Message(boolean isSearch, int max, int min) {
            this.isSearch = isSearch;
            this.max = max;
            this.min = min;
        }
    }


    public Message process(Node node){
        if (node == null) {
            return null;
        }

        Message leftMessage = process(node.left);//左边的信息
        Message rightMessage = process(node.right);//右边的信息

        int max = Math.max(leftMessage.max, rightMessage.max);
        max = Math.max(max,node.value);//当前节点和左右节点的值比较得出最大值
        int min = Math.min(leftMessage.min, rightMessage.min);
        min = Math.min(min,node.value);

        boolean isSearch = leftMessage.isSearch && rightMessage.isSearch
                && leftMessage.max < node.value && rightMessage.min > node.value;
        //左右子树都为搜索二叉树,左子树max < 当前节点的值 < 右子树min;暂不考虑等于的情况

        return new Message(isSearch,max,min);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值