左神视频day05——题目六、七:判断平衡二叉树、二叉搜索树、完全二叉树

  • 平衡二叉树:任何一个节点的左右子树高度只差 <=1
  • 二叉搜索树(BST,Binary Search Tree):对于一棵树上任何一个节点的子树,左子树 < 节点 < 右子树 。通常不出现重复节点,如果有重复节点,可以把它们的值压缩在一个节点的内部。
  • 完全二叉树(CBT,Complete Binary Tree):①某个节点有右孩子没有左孩子,则不是完全二叉树;②满足①的条件下,某个节点没有右孩子,有左孩子,或者没有左右孩子时,后面遇到的所有节点必须是叶节点。
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;

public class Code_07_IsBSTAndCBT {

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

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

    //一.判断是否是平衡二叉树
    public static class ReturnData {
        public boolean isB;
        public int h;

        public ReturnData(boolean isB, int h) {
            this.isB = isB;
            this.h = h;
        }
    }

    public static ReturnData process(Node head) {
        if (head == null) {
            return new ReturnData(true, 0);
        }
        ReturnData leftData = process(head.left);
        if (!leftData.isB) {
            return new ReturnData(false, 0);
        }
        ReturnData rightData = process(head.right);
        if (!rightData.isB) {
            return new ReturnData(false, 0);
        }
        if (Math.abs(leftData.h - rightData.h) > 1) {
            return new ReturnData(false, 0);
        }
        return new ReturnData(true, Math.max(leftData.h, rightData.h) + 1);
    }

    public static Boolean isB(Node head) {
        return process(head).isB;
    }

    //二.判断是否是二叉搜索树
    //递归
    int pre = Integer.MIN_VALUE;
    public static Boolean isBST1(Node head) {
        boolean res = true;
        if (head == null) {
            return res;
        }
        isBST1(head.left);
        if (head.value > pre) {
            pre = head.value;
        } else {
            res = false;
        }
        isBST1(head.right);
        return res;
    }

    //非递归
    public static Boolean isBST2(Node head) {
        int pre = Integer.MIN_VALUE;
        boolean res = true;
        if (head != null) {
            Stack<Node> stack = new Stack<>();
            while (!stack.isEmpty() || head != null) {
                if (head != null) {
                    stack.push(head);
                    head = head.left;
                } else {
                    head = stack.pop();
                    if (head.value > pre) {
                        pre = head.value;
                    } else {
                        res = false;
                    }
                    head = head.right;
                }
            }
        }
        return res;
    }

    //三.判断是否是完全二叉树
    public static boolean isCBT(Node head) {
        if (head == null) {
            return true;
        }
        //LinkedList是双端链表,可以实现队列结构
        Queue<Node> queue = new LinkedList<Node>();
        boolean leaf = false;
        Node l = null;
        Node r = null;
        queue.offer(head);
        while (!queue.isEmpty()) {
            head = queue.poll();
            l = head.left;
            r = head.right;

            /**
             * 判断完全二叉树的两个标准:①某个节点有右孩子没有左孩子,则不是完全二叉树
             * ②满足①的条件下,某个节点没有右孩子有左孩子,或者没有左右孩子时,后面遇到的所有节点必须是叶节点。
             */
            if ((leaf && (l != null || r != null)) || (l == null && r != null)) {
                return false;
            }

            if (l != null) {
                queue.offer(l);
            }
            if (r != null) {
                queue.offer(r);
            }
            if (l == null || r == null) {
                leaf = true;
            }
        }
        return true;
    }

    // for test -- print tree  直观打印
    public static void printTree(Node head) {
        System.out.println("Binary Tree:");
        printInOrder(head, 0, "H", 17);
        System.out.println();
    }

    public static void printInOrder(Node head, int height, String to, int len) {
        if (head == null) {
            return;
        }
        printInOrder(head.right, height + 1, "v", len);
        String val = to + head.value + to;
        int lenM = val.length();
        int lenL = (len - lenM) / 2;
        int lenR = len - lenM - lenL;
        val = getSpace(lenL) + val + getSpace(lenR);
        System.out.println(getSpace(height * len) + val);
        printInOrder(head.left, height + 1, "^", len);
    }

    public static String getSpace(int num) {
        String space = " ";
        StringBuffer buf = new StringBuffer("");
        for (int i = 0; i < num; i++) {
            buf.append(space);
        }
        return buf.toString();
    }

    public static void main(String[] args) {
        Node head = new Node(5);
        head.left = new Node(3);
        head.right = new Node(8);
        head.left.left = new Node(2);
        head.left.right = new Node(4);
        head.right.left = new Node(6);
        head.right.right = new Node(10);
        head.left.left.left = new Node(1);
        head.right.left.right = new Node(7);
        head.right.right.left = new Node(9);

        printTree(head);
        System.out.println(isB(head));     //true
        System.out.println(isBST1(head));  //true
        System.out.println(isBST2(head));  //true
        System.out.println(isCBT(head));   //false
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值