[左神面试指南] 二叉树[上]篇

CD161 用递归和非递归方式实现二叉树先序、中序和后序遍历❗

public class CD161_1
{
    public static class TreeNode
    {
        public int val;
        public TreeNode left;
        public TreeNode right;

        public TreeNode(int num)
        {
            this.val = num;
        }

        public static TreeNode createTree(int[][] edges, int root)
        {
            TreeNode[] treeNodes = new TreeNode[edges.length + 1];
            Arrays.setAll(treeNodes, TreeNode::new);
            for (int i = 0; i < edges.length; i++)
            {
                if (edges[i][1] != 0)
                    treeNodes[edges[i][0]].left = treeNodes[edges[i][1]];
                if (edges[i][2] != 0)
                    treeNodes[edges[i][0]].right = treeNodes[edges[i][2]];
            }
            return treeNodes[root];
        }
    }

    public static void solutionPre(TreeNode root)
    {
        if (root == null) return;
        Stack<TreeNode> stack = new Stack<>();
        stack.add(root);
        while (!stack.isEmpty())
        {
            TreeNode popNode = stack.pop();
            System.out.print(popNode.val + " ");
            if (popNode.right != null)
                stack.add(popNode.right);
            if (popNode.left != null)
                stack.add(popNode.left);
        }
        System.out.println();
    }

    public static void solutionIn(TreeNode root)
    {
        Stack<TreeNode> stack = new Stack<>();
        while (!stack.isEmpty() || root != null)
        {
            if (root != null)
            {
                stack.add(root);
                root = root.left;
            }
            else
            {
                root = stack.pop();
                System.out.print(root.val + " ");
                root = root.right;
            }
        }
        System.out.println();
    }

    public static void solutionPos1(TreeNode root)
    {
        if (root == null) return;
        Stack<TreeNode> s1 = new Stack<>();
        Stack<TreeNode> s2 = new Stack<>();
        s1.push(root);
        while (!s1.isEmpty())
        {
            root = s1.pop();
            s2.push(root);
            if (root.left != null)
                s1.push(root.left);
            if (root.right != null)
                s1.push(root.right);
        }
        while (!s2.isEmpty())
            System.out.print(s2.pop().val + " ");
        System.out.println();
    }

    public static void solutionPos2(TreeNode root)
    {
        if (root == null) return;
        Stack<TreeNode> stack = new Stack<>();
        stack.push(root);
        TreeNode c = null;
        while (!stack.isEmpty())
        {
            c = stack.peek();
            if (c.left != null && root != c.left && root != c.right)
                stack.push(c.left);
            else if (c.right != null && root != c.right)
                stack.push(c.right);
            else
            {
                System.out.print(stack.pop().val + " ");
                root = c;
            }
        }
        System.out.println();
    }

    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        int N, root;
        N = in.nextInt();
        root = in.nextInt();
        int[][] edges = new int[N][3];
        for (int i = 0; i < N; i++)
            for (int j = 0; j < 3; j++)
                edges[i][j] = in.nextInt();
        TreeNode rootNode = TreeNode.createTree(edges, root);
        solutionPre(rootNode);
        solutionIn(rootNode);
        solutionPos1(rootNode);
        solutionPos2(rootNode);
    }
}

CD162 打印二叉树的边界节点⭐

/*
 * ⭐递归⭐
 * 1. 每层的左右节点 + 叶子节点
 * 2. 左边延长线+ 右边延长线 + 叶子节点
 */
public class CD162_1
{
    public static class TreeNode
    {
        public int val;
        public TreeNode left;
        public TreeNode right;

        public TreeNode(int num)
        {
            this.val = num;
        }

        public static TreeNode createTree(int[][] edges, int root)
        {
            TreeNode[] treeNodes = new TreeNode[edges.length + 1];
            Arrays.setAll(treeNodes, TreeNode::new);
            for (int i = 0; i < edges.length; i++)
            {
                if (edges[i][1] != 0)
                    treeNodes[edges[i][0]].left = treeNodes[edges[i][1]];
                if (edges[i][2] != 0)
                    treeNodes[edges[i][0]].right = treeNodes[edges[i][2]];
            }
            return treeNodes[root];
        }
    }

    public static ArrayList<Integer> solution1(TreeNode root)
    {
        ArrayList<Integer> ans = new ArrayList<>();
        ArrayList<TreeNode[]> levels = new ArrayList<>();
        preOrder(root, levels, 0);
        for (int i = 0; i < levels.size(); i++)
            ans.add(levels.get(i)[0].val);
        findLeaf(root, ans, levels, 0);
        for (int i = levels.size() - 1; i >= 0; i--)
            if (levels.get(i)[1] != levels.get(i)[0])
                ans.add(levels.get(i)[1].val);
        return ans;
    }

    public static void findLeaf(TreeNode root, ArrayList<Integer> ans, ArrayList<TreeNode[]> levels, int depth)
    {
        if (root == null) return;
        if (root.left == null && root.right == null && root != levels.get(depth)[0] && root != levels.get(depth)[1]) ans.add(root.val);
        findLeaf(root.left, ans, levels, depth + 1);
        findLeaf(root.right, ans, levels, depth + 1);
    }

    public static void preOrder(TreeNode root, ArrayList<TreeNode[]> levels, int depth)
    {
        if (root == null) return;
        if (depth + 1 > levels.size()) levels.add(new TreeNode[]{null, null});
        levels.get(depth)[0] = (levels.get(depth)[0] == null ? root : levels.get(depth)[0]);
        levels.get(depth)[1] = root;
        preOrder(root.left, levels, depth + 1);
        preOrder(root.right, levels, depth + 1);
    }

    public static ArrayList<Integer> solution2(TreeNode head)
    {
        if (head == null) return null;
        ArrayList<Integer> ans = new ArrayList<>();
        ans.add(head.val);
        while (true)
        {
            if (head.left == null) head = head.right;
            else if (head.right == null) head = head.left;
            else
            {
                printLeftEdge(head.left, true, ans);
                printRightEdge(head.right, true, ans);
                break;
            }
        }
        return ans;
    }

    public static void printLeftEdge(TreeNode h, boolean print, ArrayList<Integer> ans)
    {
        if (h == null) return;
        if (print || (h.left == null && h.right == null))
            ans.add(h.val);
        printLeftEdge(h.left, print, ans);
        printLeftEdge(h.right, print && h.left == null, ans);
    }

    public static void printRightEdge(TreeNode h, boolean print, ArrayList<Integer> ans)
    {
        if (h == null) return;
        printRightEdge(h.left, print && h.right == null, ans);
        printRightEdge(h.right, print, ans);
        if (print || (h.left == null && h.right == null))
            ans.add(h.val);
    }

    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        int N, root;
        N = in.nextInt();
        root = in.nextInt();
        int[][] edges = new int[N][3];
        for (int i = 0; i < N; i++)
            for (int j = 0; j < 3; j++)
                edges[i][j] = in.nextInt();
        TreeNode rootNode = TreeNode.createTree(edges, root);
        ArrayList<Integer> res = solution1(rootNode);
        System.out.println(res.stream().map(String::valueOf).collect(Collectors.joining(" ")));
        res = solution2(rootNode);
        System.out.println(res.stream().map(String::valueOf).collect(Collectors.joining(" ")));
    }
}

CDXXX 如何较为直观地打印二叉树

CD163 二叉树的序列化和反序列化

/* 模拟 */
public class CD163_1
{
    public static class TreeNode
    {
        public int val;
        public TreeNode left;
        public TreeNode right;

        public TreeNode(int num)
        {
            this.val = num;
        }

        public static TreeNode createTree(int[][] edges, int root)
        {
            TreeNode[] treeNodes = new TreeNode[edges.length + 1];
            Arrays.setAll(treeNodes, TreeNode::new);
            for (int i = 0; i < edges.length; i++)
            {
                if (edges[i][1] != 0)
                    treeNodes[edges[i][0]].left = treeNodes[edges[i][1]];
                if (edges[i][2] != 0)
                    treeNodes[edges[i][0]].right = treeNodes[edges[i][2]];
            }
            return treeNodes[root];
        }
    }

    public static String solutionEncodePre(TreeNode root)
    {
        if (root == null) return "#!";
        String ans = root.val + "!";
        String left = solutionEncodePre(root.left);
        String right = solutionEncodePre(root.right);
        return ans + left + right;
    }

    public static TreeNode solutionDecodePre(String str)
    {
        String[] words = str.split("!");
        Queue<String> que = new LinkedList<>();
        Collections.addAll(que, words);
        return createDecodePre(que);
    }

    public static TreeNode createDecodePre(Queue<String> que)
    {
        String pollNode = que.poll();
        if ("#".equals(pollNode)) return null;
        TreeNode root = new TreeNode(Integer.parseInt(pollNode));
        root.left = createDecodePre(que);
        root.right = createDecodePre(que);
        return root;
    }

    public static TreeNode solutionDecodeLevel(String str)
    {
        Queue<TreeNode> que = new LinkedList<>();
        String[] words = str.split("!");
        int idx = 0;
        if ("#".equals(words[idx])) return null;
        TreeNode root = new TreeNode(Integer.parseInt(words[idx]));
        que.add(root);
        idx++;
        while (!que.isEmpty())
        {
            TreeNode pollNode = que.poll();
            if ("#".equals(words[idx]))
                pollNode.left = null;
            else
            {
                pollNode.left = new TreeNode(Integer.parseInt(words[idx]));
                que.add(pollNode.left);
            }
            idx++;
            if ("#".equals(words[idx]))
                pollNode.right = null;
            else
            {
                pollNode.right = new TreeNode(Integer.parseInt(words[idx]));
                que.add(pollNode.right);
            }
            idx++;
        }
        return root;
    }

    public static String solutionEncodeLevel(TreeNode root)
    {
        StringBuilder ans = new StringBuilder();
        Queue<TreeNode> que = new LinkedList<>();
        que.add(root);
        while (!que.isEmpty())
        {
            TreeNode pollNode = que.poll();
            if (pollNode != null)
                ans.append(pollNode.val + "!");
            else
                ans.append("#!");
            if (pollNode != null)
            {
                que.add(pollNode.left);
                que.add(pollNode.right);
            }
        }
        return ans.toString();
    }

    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        PrintWriter out = new PrintWriter(System.out);
        int N, root;
        N = in.nextInt();
        root = in.nextInt();
        int[][] edges = new int[N][3];
        for (int i = 0; i < N; i++)
            for (int j = 0; j < 3; j++)
                edges[i][j] = in.nextInt();
        TreeNode rootNode = TreeNode.createTree(edges, root);
        // 同时这么搞, 会超时
        out.println(solutionEncodePre(solutionDecodePre(solutionEncodePre(rootNode))));
        out.println(solutionEncodeLevel(solutionDecodeLevel(solutionEncodeLevel(rootNode))));
        out.flush();
    }
}

CD164 遍历二叉树的神级方法❗

/* ❗morris❗ */
public class CD164_1
{
    public static class TreeNode
    {
        public int val;
        public TreeNode left;
        public TreeNode right;

        public TreeNode(int num)
        {
            this.val = num;
        }

        public static TreeNode createTree(int[][] edges, int root)
        {
            TreeNode[] treeNodes = new TreeNode[edges.length + 1];
            Arrays.setAll(treeNodes, TreeNode::new);
            for (int i = 0; i < edges.length; i++)
            {
                if (edges[i][1] != 0)
                    treeNodes[edges[i][0]].left = treeNodes[edges[i][1]];
                if (edges[i][2] != 0)
                    treeNodes[edges[i][0]].right = treeNodes[edges[i][2]];
            }
            return treeNodes[root];
        }
    }

    public static void solutionPre(TreeNode root)
    {
        if (root == null) return;
        TreeNode cur = root;
        TreeNode mostRight = null;
        while (cur != null)
        {
            mostRight = cur.left;
            if (mostRight != null)
            {
                while (mostRight.right != null && mostRight.right != cur)
                    mostRight = mostRight.right;
                if (mostRight.right == null)
                {
                    mostRight.right = cur;
                    System.out.print(cur.val + " ");
                    cur = cur.left;
                    continue;
                }
                else
                    mostRight.right = null;
            }
            else
                System.out.print(cur.val + " ");
            cur = cur.right;
        }
        System.out.println();
    }

    public static void solutionIn(TreeNode root)
    {
        if (root == null) return;
        TreeNode cur = root;
        TreeNode mostRight = null;
        while (cur != null)
        {
            mostRight = cur.left;
            if (mostRight != null)
            {
                while (mostRight.right != null && mostRight.right != cur)
                    mostRight = mostRight.right;
                if (mostRight.right == null)
                {
                    mostRight.right = cur;
                    cur = cur.left;
                    continue;
                }
                else
                    mostRight.right = null;
            }
            System.out.print(cur.val + " ");
            cur = cur.right;
        }
        System.out.println();
    }

    public static void solutionPos(TreeNode root)
    {
        if (root == null) return;
        TreeNode cur = root;
        TreeNode mostRight = null;
        while (cur != null)
        {
            mostRight = cur.left;
            if (mostRight != null)
            {
                while (mostRight.right != null && mostRight.right != cur)
                    mostRight = mostRight.right;
                if (mostRight.right == null)
                {
                    mostRight.right = cur;
                    cur = cur.left;
                    continue;
                }
                else
                {
                    mostRight.right = null;
                    printEdge(cur.left);
                }
            }
            cur = cur.right;
        }
        printEdge(root);
        System.out.println();
    }

    public static void printEdge(TreeNode root)
    {
        TreeNode tail = reverseEdge(root);
        TreeNode cur = tail;
        while (cur != null)
        {
            System.out.print(cur.val + " ");
            cur = cur.right;
        }
        reverseEdge(tail);
    }

    public static TreeNode reverseEdge(TreeNode from)
    {
        TreeNode pre = null;
        TreeNode next = null;
        while (from != null)
        {
            next = from.right;
            from.right = pre;
            pre = from;
            from = next;
        }
        return pre;
    }

    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        int N, root;
        N = in.nextInt();
        root = in.nextInt();
        int[][] edges = new int[N][3];
        for (int i = 0; i < N; i++)
            for (int j = 0; j < 3; j++)
                edges[i][j] = in.nextInt();
        TreeNode rootNode = TreeNode.createTree(edges, root);
        solutionPre(rootNode);
        solutionIn(rootNode);
        solutionPos(rootNode);
    }
}

CD165 在二叉树中找到累加和为指定值的最长路径长度

/* (x->y) = (root->y) - (root->x) */
public class CD165_1
{
    public static class TreeNode
    {
        public int val;
        public TreeNode left;
        public TreeNode right;

        public TreeNode(int num)
        {
            this.val = num;
        }

        public static TreeNode createTree(int[][] edges, int root)
        {
            TreeNode[] treeNodes = new TreeNode[edges.length + 1];
            Arrays.setAll(treeNodes, TreeNode::new);
            for (int i = 0; i < edges.length; i++)
            {
                treeNodes[edges[i][0]].val = edges[i][3];
                if (edges[i][1] != 0)
                    treeNodes[edges[i][0]].left = treeNodes[edges[i][1]];
                if (edges[i][2] != 0)
                    treeNodes[edges[i][0]].right = treeNodes[edges[i][2]];
            }
            return treeNodes[root];
        }
    }

    public static int solution(TreeNode root, int SUM)
    {
        HashMap<Integer, Integer> map = new HashMap<>();
        int[] ans = new int[1];
        map.put(0, 0);
        inOrder(root, 0, 1, SUM, ans, map);
        return ans[0];
    }

    public static void inOrder(TreeNode root, int curSum, int depth, int SUM, int[] ans, HashMap<Integer, Integer> map)
    {
        if (root == null) return;
        curSum += root.val;
        if (!map.containsKey(curSum))
            map.put(curSum, depth);
        if (map.containsKey(curSum - SUM))
            ans[0] = Math.max(ans[0], depth - map.get(curSum - SUM));
        inOrder(root.left, curSum, depth + 1, SUM, ans, map);
        inOrder(root.right, curSum, depth + 1, SUM, ans, map);
        if (depth == map.get(curSum))
            map.remove(curSum);
    }

    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        int N, root, SUM;
        N = in.nextInt();
        root = in.nextInt();
        int[][] edges = new int[N][4];
        for (int i = 0; i < N; i++)
            for (int j = 0; j < 4; j++)
                edges[i][j] = in.nextInt();
        SUM = in.nextInt();
        TreeNode rootNode = TreeNode.createTree(edges, root);
        System.out.println(solution(rootNode, SUM));
    }
}

CD166 找到二叉树中的最大搜索二叉子树⭐

/* ⭐树形DP⭐ */
public class CD166_1
{
    public static class TreeNode
    {
        public int val;
        public TreeNode left;
        public TreeNode right;

        public TreeNode(int num)
        {
            this.val = num;
        }

        public static TreeNode createTree(int[][] edges, int root)
        {
            TreeNode[] treeNodes = new TreeNode[edges.length + 1];
            Arrays.setAll(treeNodes, TreeNode::new);
            for (int i = 0; i < edges.length; i++)
            {
                if (edges[i][1] != 0)
                    treeNodes[edges[i][0]].left = treeNodes[edges[i][1]];
                if (edges[i][2] != 0)
                    treeNodes[edges[i][0]].right = treeNodes[edges[i][2]];
            }
            return treeNodes[root];
        }
    }

    public static int solution(TreeNode root)
    {
        //int[]{treeNode.val, treeSize, val.max, val.min}
        return posOrder(root)[1];
    }

    public static int[] posOrder(TreeNode root)
    {
        if (root == null) return null;
        int[] leftRes = posOrder(root.left);
        int[] rightRes = posOrder(root.right);
        if (root.left == null && root.right == null)
            return new int[]{root.val, 1, root.val, root.val};
        else if (root.left == null)
        {
            if (root.right.val == rightRes[0] && root.val < rightRes[3])
                return new int[]{root.val, 1 + rightRes[1], rightRes[2], root.val};
            else
                return new int[]{rightRes[0], rightRes[1], Integer.MAX_VALUE, Integer.MIN_VALUE};
        }
        else if (root.right == null)
        {
            if (root.left.val == leftRes[0] && root.val > leftRes[2])
                return new int[]{root.val, 1 + leftRes[1], root.val, leftRes[3]};
            else
                return new int[]{leftRes[0], leftRes[1], Integer.MAX_VALUE, Integer.MIN_VALUE};
        }
        else
        {
            if (root.left.val == leftRes[0] && root.right.val == rightRes[0] && root.val > leftRes[2] && root.val < rightRes[3])
                return new int[]{root.val, 1 + leftRes[1] + rightRes[1], rightRes[2], leftRes[3]};
            else
                return new int[]{leftRes[1] > rightRes[1] ? leftRes[0] : rightRes[0], Math.max(leftRes[1], rightRes[1]), Integer.MAX_VALUE, Integer.MIN_VALUE};
        }
    }


    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        int N, root;
        N = in.nextInt();
        root = in.nextInt();
        int[][] edges = new int[N][3];
        for (int i = 0; i < N; i++)
            for (int j = 0; j < 3; j++)
                edges[i][j] = in.nextInt();
        TreeNode rootNode = TreeNode.createTree(edges, root);
        System.out.println(solution(rootNode));
    }
}

CD167 找到二叉树中符合搜索二叉树条件的最大拓扑结构❗

/* ❗(递归) 枚举每个节点, 统计个数❗ */
public class CD167_1
{
    public static class TreeNode
    {
        public int val;
        public TreeNode left;
        public TreeNode right;

        public TreeNode(int num)
        {
            this.val = num;
        }

        public static TreeNode createTree(int[][] edges, int root)
        {
            TreeNode[] treeNodes = new TreeNode[edges.length + 1];
            Arrays.setAll(treeNodes, TreeNode::new);
            for (int i = 0; i < edges.length; i++)
            {
                if (edges[i][1] != 0)
                    treeNodes[edges[i][0]].left = treeNodes[edges[i][1]];
                if (edges[i][2] != 0)
                    treeNodes[edges[i][0]].right = treeNodes[edges[i][2]];
            }
            return treeNodes[root];
        }
    }

    public static int solution(TreeNode root)
    {
        if (root == null) return 0;
        int ans = cal(root, root);
        ans = Math.max(ans, solution(root.left));
        ans = Math.max(ans, solution(root.right));
        return ans;
    }

    public static int cal(TreeNode root, TreeNode node)
    {
        if (node == null) return 0;
        if (judgeBinSearch(root, node))
            return 1 + cal(root, node.left) + cal(root, node.right);
        return 0;
    }

    public static boolean judgeBinSearch(TreeNode root, TreeNode node)
    {
        if (root == null) return false;
        if (root == node) return true;
        return judgeBinSearch(root.val > node.val ? root.left : root.right, node);
    }


    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        int N, root;
        N = in.nextInt();
        root = in.nextInt();
        int[][] edges = new int[N][3];
        for (int i = 0; i < N; i++)
            for (int j = 0; j < 3; j++)
                edges[i][j] = in.nextInt();
        TreeNode rootNode = TreeNode.createTree(edges, root);
        System.out.println(solution(rootNode));
    }
}

/* ❗拓扑贡献记录❗ */
public class CD167_2
{
    public static class TreeNode
    {
        public int val;
        public TreeNode left;
        public TreeNode right;

        public TreeNode(int num)
        {
            this.val = num;
        }

        public static TreeNode createTree(int[][] edges, int root)
        {
            TreeNode[] treeNodes = new TreeNode[edges.length + 1];
            Arrays.setAll(treeNodes, TreeNode::new);
            for (int i = 0; i < edges.length; i++)
            {
                if (edges[i][1] != 0)
                    treeNodes[edges[i][0]].left = treeNodes[edges[i][1]];
                if (edges[i][2] != 0)
                    treeNodes[edges[i][0]].right = treeNodes[edges[i][2]];
            }
            return treeNodes[root];
        }
    }

    public static int solution(TreeNode root)
    {
        HashMap<TreeNode, int[]> map = new HashMap<>();
        return posOrder(root, map);
    }

    public static int posOrder(TreeNode root, HashMap<TreeNode, int[]> map)
    {
        if (root == null) return 0;
        int lRes = posOrder(root.left, map);
        int rRes = posOrder(root.right, map);
        modifyMap(root.left, root.val, map, true);
        modifyMap(root.right, root.val, map, false);
        int[] lArr = map.get(root.left);
        int[] rArr = map.get(root.right);
        int l = (lArr == null ? 0 : lArr[0] + lArr[1] + 1);
        int r = (rArr == null ? 0 : rArr[0] + rArr[1] + 1);
        map.put(root, new int[]{l, r});
        return Math.max(l + r + 1, Math.max(lRes, rRes));
    }

    public static void modifyMap(TreeNode root, int val, HashMap<TreeNode, int[]> map, boolean isLeft)
    {
        TreeNode temp = root;
        if (temp == null || !map.containsKey(temp)) return;
        while (temp != null && (!isLeft || temp.val < val) && (isLeft || temp.val > val))
        {
            if (!map.containsKey(temp)) return;
            if (isLeft) temp = temp.right;
            else temp = temp.left;
        }
        if (temp == null) return;
        int tl = map.get(temp)[0];
        int tr = map.get(temp)[1];
        map.remove(temp);
        while (root != temp)
        {
            int l = map.get(root)[0];
            int r = map.get(root)[1];
            if (isLeft)
            {
                map.put(root, new int[]{l, r - tl - tr - 1});
                root = root.right;
            }
            else
            {
                map.put(root, new int[]{l - tl - tr - 1, r});
                root = root.left;
            }
        }
    }

    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        int N, root;
        N = in.nextInt();
        root = in.nextInt();
        int[][] edges = new int[N][3];
        for (int i = 0; i < N; i++)
            for (int j = 0; j < 3; j++)
                edges[i][j] = in.nextInt();
        TreeNode rootNode = TreeNode.createTree(edges, root);
        System.out.println(solution(rootNode));
    }
}

CD168 二叉树的按层打印与 ZigZag 打印

/* 模拟(左神用的双端队列) */
public class CD168_1
{
    public static class TreeNode
    {
        public int val;
        public TreeNode left;
        public TreeNode right;

        public TreeNode(int num)
        {
            this.val = num;
        }

        public static TreeNode createTree(int[][] edges, int root)
        {
            TreeNode[] treeNodes = new TreeNode[edges.length + 1];
            Arrays.setAll(treeNodes, TreeNode::new);
            for (int i = 0; i < edges.length; i++)
            {
                if (edges[i][1] != 0)
                    treeNodes[edges[i][0]].left = treeNodes[edges[i][1]];
                if (edges[i][2] != 0)
                    treeNodes[edges[i][0]].right = treeNodes[edges[i][2]];
            }
            return treeNodes[root];
        }
    }

    public static void solution(TreeNode root)
    {
        levelPrint(root);
        ziaPrint(root);
    }

    public static void levelPrint(TreeNode root)
    {
        if (root == null) return;
        int level = 1;
        Queue<TreeNode> que = new LinkedList<>();
        que.add(root);
        while (!que.isEmpty())
        {
            int size = que.size();
            System.out.print("Level " + level + " :");
            while (size-- > 0)
            {
                TreeNode pollNode = que.poll();
                System.out.print(" " + pollNode.val);
                if (pollNode.left != null) que.add(pollNode.left);
                if (pollNode.right != null) que.add(pollNode.right);
            }
            System.out.println();
            level++;
        }
    }

    public static void ziaPrint(TreeNode root)
    {
        if (root == null) return;
        int level = 1;
        Queue<TreeNode> que = new LinkedList<>();
        ArrayList<TreeNode> temp = new ArrayList<>();
        que.add(root);
        while (!que.isEmpty())
        {
            temp.clear();
            int size = que.size();
            while (size-- > 0)
            {
                TreeNode pollNode = que.poll();
                temp.add(pollNode);
                if (pollNode.left != null) que.add(pollNode.left);
                if (pollNode.right != null) que.add(pollNode.right);
            }
            if (level % 2 != 0)
            {
                System.out.print("Level " + level + " from left to right:");
                for (int i = 0; i < temp.size(); i++)
                    System.out.print(" " + temp.get(i).val);
            }
            else
            {
                System.out.print("Level " + level + " from right to left:");
                for (int i = temp.size() - 1; i >= 0; i--)
                    System.out.print(" " + temp.get(i).val);
            }
            System.out.println();
            level++;
        }
    }

    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        int N, root;
        N = in.nextInt();
        root = in.nextInt();
        int[][] edges = new int[N][3];
        for (int i = 0; i < N; i++)
            for (int j = 0; j < 3; j++)
                edges[i][j] = in.nextInt();
        TreeNode rootNode = TreeNode.createTree(edges, root);
        solution(rootNode);
    }
}

CD169 调整搜索二叉树中两个错误的节点

/*
 * 模拟(中序排列中找降序)
 * 若在结构上交换这两个错误节点, 会有14种情况
 */
public class CD169_1
{
    public static class TreeNode
    {
        public int val;
        public TreeNode left;
        public TreeNode right;

        public TreeNode(int num)
        {
            this.val = num;
        }

        public static TreeNode createTree(int[][] edges, int root)
        {
            TreeNode[] treeNodes = new TreeNode[edges.length + 1];
            Arrays.setAll(treeNodes, TreeNode::new);
            for (int i = 0; i < edges.length; i++)
            {
                if (edges[i][1] != 0)
                    treeNodes[edges[i][0]].left = treeNodes[edges[i][1]];
                if (edges[i][2] != 0)
                    treeNodes[edges[i][0]].right = treeNodes[edges[i][2]];
            }
            return treeNodes[root];
        }
    }

    public static void solution(TreeNode root)
    {
        ArrayList<Integer> temp = new ArrayList<>();
        ArrayList<Integer> ans = new ArrayList<>();
        inOrder(root, temp);
        for (int i = 0; i < temp.size() - 1; i++)
        {
            if (temp.get(i) > temp.get(i + 1))
            {
                ans.add(temp.get(i + 1));
                ans.add(temp.get(i));
            }
        }
        if (ans.size() == 2)
            System.out.println(ans.get(0) + " " + ans.get(1));
        else
        {
            int l = Math.max(ans.get(0), ans.get(1));
            int r = Math.min(ans.get(2), ans.get(3));
            System.out.println(Math.min(l, r) + " " + Math.max(l, r));
        }
    }

    public static void inOrder(TreeNode root, ArrayList<Integer> temp)
    {
        if (root == null) return;
        inOrder(root.left, temp);
        temp.add(root.val);
        inOrder(root.right, temp);
    }

    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        int N, root;
        N = in.nextInt();
        root = in.nextInt();
        int[][] edges = new int[N][3];
        for (int i = 0; i < N; i++)
            for (int j = 0; j < 3; j++)
                edges[i][j] = in.nextInt();
        TreeNode rootNode = TreeNode.createTree(edges, root);
        solution(rootNode);
    }
}

CD170 判断 t1 树是否包含 t2 树全部的拓扑结构

/* 枚举节点 */
public class CD170_1
{
    public static class TreeNode
    {
        public int val;
        public TreeNode left;
        public TreeNode right;

        public TreeNode(int num)
        {
            this.val = num;
        }

        public static TreeNode createTree(int[][] edges, int root)
        {
            TreeNode[] treeNodes = new TreeNode[500000 + 1];
            Arrays.setAll(treeNodes, TreeNode::new);
            for (int i = 0; i < edges.length; i++)
            {
                if (edges[i][1] != 0)
                    treeNodes[edges[i][0]].left = treeNodes[edges[i][1]];
                if (edges[i][2] != 0)
                    treeNodes[edges[i][0]].right = treeNodes[edges[i][2]];
            }
            return treeNodes[root];
        }
    }

    public static boolean solution(TreeNode root1, TreeNode root2)
    {
        if (root1 == null && root2 == null) return true;
        if (root1 == null) return false;
        return solution(root1.left, root2) || solution(root1.right, root2) || check(root1, root2);
    }

    public static boolean check(TreeNode root1, TreeNode root2)
    {
        if (root1 == null && root2 == null) return true;
        else if (root1 == null) return false;
        else if (root2 == null) return true;
        else
        {
            if (root1.val == root2.val)
                return check(root1.left, root2.left) && check(root1.right, root2.right);
            else return false;
        }
    }

    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        int N, root;
        N = in.nextInt();
        root = in.nextInt();
        int[][] edges1 = new int[N][3];
        for (int i = 0; i < N; i++)
            for (int j = 0; j < 3; j++)
                edges1[i][j] = in.nextInt();
        TreeNode rootNode1 = TreeNode.createTree(edges1, root);
        N = in.nextInt();
        root = in.nextInt();
        int[][] edges2 = new int[N][3];
        for (int i = 0; i < N; i++)
            for (int j = 0; j < 3; j++)
                edges2[i][j] = in.nextInt();
        TreeNode rootNode2 = TreeNode.createTree(edges2, root);
        System.out.println(solution(rootNode1, rootNode2));
    }
}

CD171 判断 t1 树中是否有与 t2 树拓扑结构完全相同的子树

/* 枚举节点 */
public class CD171_1
{
    public static class TreeNode
    {
        public int val;
        public TreeNode left;
        public TreeNode right;

        public TreeNode(int num)
        {
            this.val = num;
        }

        public static TreeNode createTree(int[][] edges, int root)
        {
            TreeNode[] treeNodes = new TreeNode[500000 + 1];
            Arrays.setAll(treeNodes, TreeNode::new);
            for (int i = 0; i < edges.length; i++)
            {
                if (edges[i][1] != 0)
                    treeNodes[edges[i][0]].left = treeNodes[edges[i][1]];
                if (edges[i][2] != 0)
                    treeNodes[edges[i][0]].right = treeNodes[edges[i][2]];
            }
            return treeNodes[root];
        }
    }

    public static boolean solution(TreeNode root1, TreeNode root2)
    {
        if (root1 == null && root2 == null) return true;
        if (root1 == null) return false;
        return solution(root1.left, root2) || solution(root1.right, root2) || check(root1, root2);
    }

    public static boolean check(TreeNode root1, TreeNode root2)
    {
        if (root1 == null && root2 == null) return true;
        else if (root1 == null) return false;
        else if (root2 == null) return false;
        else
        {
            if (root1.val == root2.val)
                return check(root1.left, root2.left) && check(root1.right, root2.right);
            else return false;
        }
    }

    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        int N, root;
        N = in.nextInt();
        root = in.nextInt();
        int[][] edges1 = new int[N][3];
        for (int i = 0; i < N; i++)
            for (int j = 0; j < 3; j++)
                edges1[i][j] = in.nextInt();
        TreeNode rootNode1 = TreeNode.createTree(edges1, root);
        N = in.nextInt();
        root = in.nextInt();
        int[][] edges2 = new int[N][3];
        for (int i = 0; i < N; i++)
            for (int j = 0; j < 3; j++)
                edges2[i][j] = in.nextInt();
        TreeNode rootNode2 = TreeNode.createTree(edges2, root);
        System.out.println(solution(rootNode1, rootNode2));
    }
}

/* 若t2树序列化是t1树序列化的字串, 则返回true */
public class CD171_2
{
    public static class TreeNode
    {
        public int val;
        public TreeNode left;
        public TreeNode right;

        public TreeNode(int num)
        {
            this.val = num;
        }

        public static TreeNode createTree(int[][] edges, int root)
        {
            TreeNode[] treeNodes = new TreeNode[500000 + 1];
            Arrays.setAll(treeNodes, TreeNode::new);
            for (int i = 0; i < edges.length; i++)
            {
                if (edges[i][1] != 0)
                    treeNodes[edges[i][0]].left = treeNodes[edges[i][1]];
                if (edges[i][2] != 0)
                    treeNodes[edges[i][0]].right = treeNodes[edges[i][2]];
            }
            return treeNodes[root];
        }
    }

    public static boolean solution(TreeNode root1, TreeNode root2)
    {
        return stringify(root1).contains(stringify(root2));
    }

    public static String stringify(TreeNode root)
    {
        if (root == null) return "#!";
        return root.val + "!" + stringify(root.left) + stringify(root.right);
    }

    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        int N, root;
        N = in.nextInt();
        root = in.nextInt();
        int[][] edges1 = new int[N][3];
        for (int i = 0; i < N; i++)
            for (int j = 0; j < 3; j++)
                edges1[i][j] = in.nextInt();
        TreeNode rootNode1 = TreeNode.createTree(edges1, root);
        N = in.nextInt();
        root = in.nextInt();
        int[][] edges2 = new int[N][3];
        for (int i = 0; i < N; i++)
            for (int j = 0; j < 3; j++)
                edges2[i][j] = in.nextInt();
        TreeNode rootNode2 = TreeNode.createTree(edges2, root);
        System.out.println(solution(rootNode1, rootNode2));
    }
}
posted @ 2023-11-10 20:13  Vivid-BinGo  阅读(6)  评论(0编辑  收藏  举报