鉴别完全二叉树

鉴别完全二叉树

描述

设计一个算法,判断一颗二叉树是否是完全二叉树。

分析

一颗 k 层 n 个节点的完全二叉树,和 k 层的满二叉树按层序遍历的前 n 个节点形状一致。所以,一颗完全二叉树中的任何节点如果有右儿子,那么一定有左儿子。且层序遍历时,一旦出现空节点,后续节点必定全为空。可以用一个标记标量 mode 记住是否出现过空节点。

步骤

① 初始 mode = 0
② 层序遍历二叉树, mode = 0时:当前节点有左儿子,则左儿子入队。没有左儿子则 mode 变为 1。当前节点有右儿子且 mode = 0,则右儿子入队,如果 mode = 1 则代表不是完全二叉树,返沪 false。如果没有右子,则 mode 变为 1; mode = 1时:如果当前节点有左儿子或右儿子则返回 false。
③ 遍历结束,返回 true

代码

class IsCompleteBinaryTree {
    public static boolean isCompleteBinaryTree(Node root) {
        byte mode = 0;                                  // 模式0:还未遇到任何 null 节点
        Queue<Node> queue = new LinkedList<>();
        queue.offer(root);                              // 根节点入队
        while (!queue.isEmpty()) {                      // 队列为空时循环终止
            Node cur = queue.poll();                    // 当前节点指向出队节点
            if (mode == 0) {                            // 如果是模式 0
                if (cur.left != null) {                 // 当前节点有左儿子,则左儿子入队
                    queue.offer(cur.left);
                } else {                
                    mode = 1;                           // 当前节点没有左儿子,遇到空节点,模式转为1
                }
                if (cur.right != null) {                // 如果当前节点有右儿子,但是没有左儿子,则不可能是完全二叉树,直接返回 false
                    if (mode == 1)
                    return false;
                    queue.offer(cur.right);             // 反之,右儿子入队列
                } else {
                    mode = 1;                           // 如果当前节点没有右儿子,模式转为 1
                }
            } else {                                    // 如果是模式 1,出现任何非空节点,返回 false
                if (cur.left != null || cur.right != null) {
                    return false;
                }
            }
        }
        return true;
    }
    // 节点类
    static class Node {
        Node left;
        Node right;
        public int element;
        public Node(int element) {
            this.element = element;
        }
    }
    public static void main(String[] args) {
        // 建树1
        Node tree1 = new Node(1);
        tree1.left = new Node(2);
        tree1.right = new Node(3);
        tree1.left.left  = new Node(4);
        tree1.left.right = new Node(5);
        tree1.right.left = new Node(6);      
        // 判断 tree1 是否是完全二叉树
        String rst = isCompleteBinaryTree(tree1) ? "tree1 is complete binary tree" : "tree1 is not complete binary tree";
        // 建树2
        System.out.println(rst);
        Node tree2 = new Node(1);
        tree2.left = new Node(2);
        tree2.right = new Node(3);
        tree2.left.left  = new Node(4);
        tree2.right.left = new Node(6);  
        // 判断 tree2 是否是完全二叉树
        rst = isCompleteBinaryTree(tree2) ? "tree1 is complete binary tree" : "tree1 is not complete binary tree";
        System.out.println(rst);
    }
}

out:
tree1 is complete binary tree
tree2 is not complete binary tree

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值