二叉树——判断是否是搜索二叉树和完全二叉树

1. 判断一棵二叉树是否为搜索二叉树和完全二叉树

验证二叉搜索树

二叉树的完全性检验

1.1. 问题

给定二叉树的一个头节点 head,已知其中没有重复值的节点,实现两个函数分别判断这棵二叉树是否为搜索二叉树和完全二叉树。

1.2. 思路

判断是否是搜索二叉树可用中序遍历一遍,倘若是递增序列,则为搜索二叉树。

判断是否是完全二叉树:

  • 方法一:可以用层序遍历(广度优先),当发现一个节点的左子节点或右子节点为空时,那么接下来都不能在遇到子节点。

  • 方法二:可以用深度优先搜索。一个完全二叉树可以表示为一个堆,我们在进行遍历的时候给二叉树的节点进行编号,然后将最大编号跟节点数量进行比较,如果相同则是完全二叉树,不同那么则不是。

判断一个树是否为完全搜索二叉树时,可以将判断搜索二叉树的方法和判断完全二叉树的方法二进行合并。

1.3. 代码

1.3.1. 判断是否为搜索二叉树

手动用栈模拟

    public static boolean isBST(TreeNode<Integer> root) {
        if (root == null) return true;
        Stack<TreeNode<Integer>> stack = new Stack<>();
        TreeNode<Integer> cur = root;
        TreeNode<Integer> pre = null;
        while (!stack.empty() || cur != null) {
            if (cur != null) {
                stack.push(cur);
                cur = cur.left;
            } else {
                cur = stack.pop();
                if (pre != null && pre.val > cur.val)
                    return false;
                pre = cur;
                cur = cur.right;
            }
        }
        return true;
    }

递归

class Solution {
    private long previousNodeVal = Long.MIN_VALUE;

    public boolean isValidBST(TreeNode root) {
        if(root == null) {
            return true;
        }

        if(!isValidBST(root.left)) {
            return false;
        }

        long val = root.val;
        if(val <= previousNodeVal) {
            return false;
        }
        previousNodeVal = val;

        return isValidBST(root.right);
    }
}

递归的分支优化

当一个方法中有很多检查语句,不通过返回false的话,那么我们可以将整个方法预设返回false,只用聚焦在返回为true的情况,这样会让代码更清晰。

class Solution {
    double last = -Double.MAX_VALUE;

    public boolean isValidBST(TreeNode root) {
        if (root == null) {
            return true;
        }
        if (isValidBST(root.left)) {
            if (last < root.val) {
                last = root.val;
                return isValidBST(root.right);
            }
        }
        return false;
    }
}

1.3.2. 判断是否为完全二叉树

广度优先(层序遍历)

    public static boolean isCBT(TreeNode<Integer> root) {
        if (root == null) return true;
        Queue<TreeNode<Integer>> queue = new LinkedList<>();
        TreeNode<Integer> node = root;
        queue.add(node);
        boolean isChildAllowed = true;
        while (!queue.isEmpty()) {
            node = queue.remove();
            if (node.left != null) {
                if (!isChildAllowed) return false;
                queue.add(node.left);
            } else {
                isChildAllowed = false;
            }

            if (node.right != null) {
                if (!isChildAllowed) return false;
                queue.add(node.right);
            } else {
                isChildAllowed = false;
            }
        }
        return true;
    }

深度优先

class Solution {
    private int count = 0;
    private int maxNum = 0;

    public  boolean isCompleteTree(TreeNode root) {
        if(root == null) {
            return true;
        }
        dfs(root, 1);
        return count == maxNum;
    }

    private void dfs(TreeNode head, int num) {
        count++;
        maxNum = Math.max(maxNum, num);
        if(head.left != null) {
            dfs(head.left, num * 2);
        }
        if(head.right != null) {
            dfs(head.right, num * 2 + 1);
        }
    }
posted @ 2022-05-12 11:12  迈吉  阅读(157)  评论(0)    收藏  举报