二叉树的递归套路

191 阅读3分钟

「这是我参与2022首次更文挑战的第33天,活动详情查看:2022首次更文挑战」。

一、判断二叉树是否是完全二叉树

1、分析

判断二叉树是否是完全二叉树的核心思路:二叉树的按层遍历(队列,宽度优先遍历),一个一个的判断是否出现过情况一或情况二

  • 情况一:Y节点,没有左孩子,只有右孩子,则一定不是完全二叉树

  • 情况二:当第一次遇到左右不双全,剩下节点必须为叶子节点

2、实现

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

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

public static boolean isCBT1(Node head) {
    if (head == null) {
        return true;
    }
    LinkedList<Node> queue = new LinkedList<>();
    // 是否遇到过左右两个孩子不双全的节点
    boolean leaf = false;
    Node l = null;
    Node r = null;
    queue.add(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.add(l);
        }
        if (r != null) {
            queue.add(r);
        }
        if (l == null || r == null) {
            leaf = true;
        }
    }
    return true;
}

二、判断二叉树是否是满二叉树

1、分析

满二叉树的性质:如果树的高度是h,那么节点数为2^h - 1

任何以x为头的整个树,看它的高度h与它的节点数,满不满足这个关系

2、实现

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

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

public static class Info {
    public int height;
    public int nodes;

    public Info(int h, int n) {
        height = h;
        nodes = n;
    }
}

// 收集整棵树的高度h,和节点数n
// 只有满二叉树满足 : 2 ^ h - 1 == n
public static boolean isFull(Node head) {
    if (head == null) {
        return true;
    }
    Info all = process(head);
    return (1 << all.height) - 1 == all.nodes;
}

private static Info process(Node head) {
    if (head == null) {
        return new Info1(0, 0);
    }
    Info leftInfo = process(head.left);
    Info rightInfo = process(head.right);
    int height = Math.max(leftInfo.height, rightInfo.height) + 1;
    int nodes = leftInfo.nodes + rightInfo.nodes + 1;
    return new Info(height, nodes);
}

三、整颗二叉树的最大距离

给定一棵二叉树的头节点head,任何两个节点之间都存在距离,返回整棵二叉树的最大距离

1、分析

人为规定距离就是从开始到结束的节点数量(沿途经过的节点数量)

目标:x为头的整颗树的最大距离,罗列可能性

x无关

  • 可能一:x左树上的最大距离
  • 可能二:x右树上的最大距离

x有关:x左树与x最远(左树的高度)+ x右树与x最远(右树的高度)+ 1(自身节点)

2、实现

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

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

public static class Info {
    public int maxDistance;
    public int height;

    public Info(int m, int h) {
        maxDistance = m;
        height = h;
    }
}

public static int maxDistance(Node head) {
    return process(head).maxDistance;
}

private static Info process(Node x) {
    if (x == null) {
        return new Info(0, 0);
    }
    Info leftInfo = process(x.left);
    Info rightInfo = process(x.right);
    int height = Math.max(leftInfo.height, rightInfo.height) + 1;
    int p1 = leftInfo.maxDistance;
    int p2 = rightInfo.maxDistance;
    int p3 = leftInfo.height + rightInfo.height + 1;
    int maxDistance = Math.max(Math.max(p1, p2), p3);
    return new Info(maxDistance, height);
}

四、总结

罗列可能性的时候,要想着,x有关的可能性,x无关的可能性

怎么确定有关的可能性?怎么确定无关的可能性?

这道题跟距离有关,那么x有关的可能性就是沿途中经过(路过)x,x无关的可能性就是沿途中不经过(路过)x