JAVA-二叉树2

(代码如有错误,烦请各位指正)

1.判断一棵二叉树是否是搜索二叉树

搜索二叉树(Binary Search Tree):按照中序遍历输出的值是严格递增的。
(1)使用之前的中序遍历实现

//使用中序遍历判断是不是二叉树:把中序遍历的输出变成比较即可
    static int preValue=Integer.MIN_VALUE;
    public static boolean isBinarySearchTree(Tree head){
        if(head==null){
            return true;
        }
        boolean left=isBinarySearchTree(head.left);
        if(!left){
            return false;
        }//判断左树是否是搜索二叉树
        if(head.value<=preValue){
            return false;
        }else{
            preValue= head.value;
        }//判断前一个节点是否小于当前节点,不小直接返回false,满足条件则更新当前值
        return isBinarySearchTree(head.right);
    }

(2)使用二叉树的固定套路实现
满足搜索二叉树需要满足的条件:左树和右树均是搜索二叉树,左树的最大值比我小,右数的最小值比我大
需要左树提供的条件:左树是否是搜索二叉树,左树的最大值
需要右树提供的条件:右树是否是搜索二叉树,右树的最小值
(为了方便递归,左树和右树都提供最大值和最小值)

    //2.使用二叉树的递归套路
    //自定义一个输出类
    static class BSTReturn{
        boolean isBST;
        int max;
        int min;
        public BSTReturn(boolean isBST,int max,int min){
            this.isBST=isBST;
            this.max=max;
            this.min=min;
        }
    }
    //返回当前部分是否是搜索二叉树、最大值和最小值
    public static BSTReturn processBST(Tree head){
        if(head==null){
            return null;
        }
        BSTReturn left=processBST(head.left);
        BSTReturn right=processBST(head.right);
        Boolean isBST=true;
        int max=head.value;
        int min=head.value;
        //找到最大值和最小值
        if(left!=null){
            min=Math.min(min,left.min);
            max=Math.max(max,left.max);
        }
        if(right!=null){
            min=Math.min(min,right.min);
            max=Math.max(max, right.max);
        }
        //判断是否是搜索二叉树
        if(left!=null && (!left.isBST || left.max >= head.value)){
            isBST=false;
        }
        if(right!=null && (!right.isBST || right.min<=head.value)){
            isBST=false;
        }
        return new BSTReturn(isBST,max,min);
    }
    //判断结果
    public static boolean isBinarySearchTree2(Tree head){
        if(head==null){
            return true;
        }
        return processBST(head).isBST;
    }

2.判断一棵树是否是完全二叉树

完全二叉树:要不是满,最后一层一定是满或者从左往右依次变满。
使用宽度遍历:当前节点有右无左,直接返回false;只要出现一个节点是叶子节点或者只有左孩子,那么接下来每一个节点都必须是叶节点。

    //判断是否是完全二叉树
    public static Boolean isCompleteBinaryTree(Tree head){
        if(head==null){
            return true;
        }
        Queue<Tree> queue=new LinkedList<>();
        Boolean label=false;
        queue.add(head);
        while(!queue.isEmpty()){
            Tree cur=queue.poll();
            if(
                    (cur.left==null && cur.right!=null)//有右无左
                    ||
                    (label && (cur.left!=null || cur.right !=null))//已经出现了label=true的节点,但接下来的节点还有左或者右
            ){
                return false;
            }

            if(cur.left!=null){
                queue.add(cur.left);
            }
            if(cur.right!=null){
                queue.add(cur.right);
            }
            //出现第一个叶节点或者只有左孩子的节点
            if(cur.left==null || cur.right==null){
                label=true;
            }
        }
        return true;
    }

3.判断一棵树是否是满二叉树

满二叉树(full binary tree):深度d和节点个数n满足:n=2d-1
使用递归套路来解题
满二叉树需要满足的条件:满足n=2d-1的条件
需要左树提供的信息:深度,节点个数
需要右树提供的信息:深度,节点个数

    //3.判断是否是满二叉树
    static class FBTReturn{
        int height;
        int nodeNum;
        public FBTReturn(int height,int nodeNum){
            this.height=height;
            this.nodeNum=nodeNum;
        }
    }
    public static FBTReturn FBTProcess(Tree head){
        if(head==null){
            return new FBTReturn(0,0);
        }
        FBTReturn left=FBTProcess(head.left);
        FBTReturn right=FBTProcess(head.right);
        int height=Math.max(left.height, right.height)+1;
        int nodeNum= left.nodeNum+right.nodeNum+1;
        return new FBTReturn(height,nodeNum);
    }
    public static Boolean isFullBinaryTree(Tree head){
        if(head==null){
            return true;
        }
        int height=FBTProcess(head).height;
        int nodeNum=FBTProcess(head).nodeNum;
        if(nodeNum!=2*height-1){
            return false;
        }
        return true;
    }

4.判断一棵树是否是平衡二叉树

平衡二叉树(Self-balancing Binary Search Tree,AVL树):其左子树和右子树均为平衡二叉树,且左子树和右子树的高度差的绝对值不超过1
使用二叉树套路解题:
是AVL数需要满足的条件:左右子树均是AVL树,且高度差不超过1
需要左树提供的信息:是否是AVL树,高度
需要右树提供的信息:是否是AVL树,高度

    //5.判断是否是AVL树
    static class AVLReturn{
        Boolean isAVL;
        int height;
        public AVLReturn(Boolean isAVL,int height){
            this.isAVL=isAVL;
            this.height=height;
        }
    }
    public static AVLReturn AVLProcess(Tree head){
        if(head==null){
            return new AVLReturn(true,0);
        }
        AVLReturn left=AVLProcess(head.left);
        AVLReturn right=AVLProcess(head.right);
        int height=Math.max(left.height, right.height)+1;
        Boolean isAVL;
        if(left.isAVL && right.isAVL && Math.abs(left.height-right.height)<2){
            isAVL=true;
        }else{
            isAVL=false;
        }
        return new AVLReturn(isAVL,height);
    }
    public static Boolean isAVL(Tree head){
        return AVLProcess(head).isAVL;
    }

5.给定两个二叉树的节点node1和node2,找到他们的最低公共祖先节点

(1)使用哈希表存储每一个节点的父节点;把node1的父节点存到一个列表里,遍历node2的父节点,直到列表里也有该父节点

    //6.最低公共祖先节点
    //(1)使用哈希表
    public static Tree lowCommentNode(Tree head,Tree node1,Tree node2){
        if(head==null || node1==null || node2==null){
            return null;
        }
        //找到所有节点的父节点并一一对应
        HashMap<Tree,Tree> hashmap=new HashMap<>();
        hashmap.put(head,head);//根节点的父节点是他自己
        findFatherMap(head,hashmap);

        //存储node1本身以及它的祖先节点
        HashSet<Tree> hashset=new HashSet<>();
        Tree cur=node1;
        while(hashmap.get(cur)!=cur){
            hashset.add(cur);//自己也要存
            cur=hashmap.get(cur);
        }
        hashset.add(head);//根节点也要存
        
        cur=node2;
        while(hashmap.get(cur)!=cur){
            if(hashset.contains(cur)){
                return cur;
            }else{
                cur=hashmap.get(cur);
            }
        }
        return null;
    }
    public static void findFatherMap(Tree head, HashMap<Tree,Tree> hashmap){
        if(head==null){
            return;
        }
        hashmap.put(head.left,head);
        hashmap.put(head.right,head);
        findFatherMap(head.left,hashmap);
        findFatherMap(head.right,hashmap);
    }

(2)

    //(2)
    public static Tree findLCN(Tree head,Tree node1,Tree node2){
        if(head==null || head==node1 || head==node2){
            return head;
        }
        Tree left=findLCN(head.left,node1,node2);
        Tree right=findLCN(head.right,node1,node2);
        if(left!=null && left!=null){
            return head;
        }
        return left!=null ? left:right;
    }

6.在二叉树中找一个节点的后继节点

中序遍历循序该节点的后一个节点叫做该节点的后继节点
该节点有右树:则为该右树上的最左节点;无右树:在上找节点是父节点的左孩子,则该父节点即为所求

    //7.找后继节点
    public static Tree getSuccsseorNode(Tree node){
        if(node==null){
            return null;
        }
        if(node.right!=null){
            return getMostLeftNode(node.right);
        }else{
            Tree parent =node.parent;
            while(parent!=null && parent.left!=null){
                node=parent;
                parent=node.parent;
            }
            return parent;
        }
    }
    public static Tree getMostLeftNode(Tree node){
        if(node==null){
            return null;
        }
        while(node.left!=null){
            node=node.left;
        }
        return null;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值