• 算法


    二叉树

    二叉树按层遍历打印

    宽度优先遍历,通常使用队列结构。常常有按照层数换行的问题。

    		    1
             /     
            2		3
           /       / 
          4       5   6
                 / 
                7   8    
    output:
    1
    2 3
    4 5 6
    7 8
    

    思路:

    这时可以使用两个变量记录,一个是用变量 last 记录当前的 last 结点,另一个是用变量 nlast 记录下一层的 last 结点。

    pop() 时添加子树,如果 pop 值等于 last 指向的变量,打印换行符号,last 变量指向 nlast。

    nlast 跟踪的是最新加入 queue 的数。

    实现:

    public void printTree(TreeNode root) {
        TreeNode last = null;
        TreeNode nlast = null;
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        last = root;
        nlast = root;
        while (!queue.isEmpty()) {
            TreeNode tmp = queue.poll();
            System.out.print(tmp.val + " ");
            if (tmp.left != null) {
                queue.offer(tmp.left);
                nlast = tmp.left;
            }
            if (tmp.right != null) {
                queue.offer(tmp.right);
                nlast = tmp.right;
            }
            if (tmp == last) {
                last = nlast;
                System.out.println();
            }
        }
    }
    

    测试:

    public static void main(String[] args) {
        // 构建二叉树
        TreeNode root = new TreeNode(1);
        root.left = new TreeNode(2);
        root.right = new TreeNode(3);
        root.left.left = new TreeNode(4);
        root.right.left = new TreeNode(5);
        root.right.right = new TreeNode(6);
        root.right.left.left = new TreeNode(7);
        root.right.left.right = new TreeNode(8);
        PrintBinaryTree test = new PrintBinaryTree();
        test.printTree(root);
    }
    

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

    方式:先序遍历,中序遍历,后序遍历,层序遍历。

    给定一个二叉树的头节点 head,节点值的类型是 32 位整型。设计序列化和反序列化方案。

    使用树的前序遍历实现序列化:

    public static String serializedBinaryTree(TreeNode root) {
        StringBuilder sb = new StringBuilder();
        preOrderTraversal(root, sb);
        return sb.toString();
    }
    
    private static void preOrderTraversal(TreeNode node, StringBuilder sb) {
        if (node == null) {
            sb.append("#!");
            return;
        }
        sb.append(node.val).append("!");
        preOrderTraversal(node.left, sb);
        preOrderTraversal(node.right, sb);
    }
    

    测试:

    public static void main(String[] args) {
        // 构建二叉树
        TreeNode root = new TreeNode(1);
        root.left = new TreeNode(2);
        root.right = new TreeNode(3);
        root.left.left = new TreeNode(4);
        root.right.left = new TreeNode(5);
        root.right.right = new TreeNode(6);
        root.right.left.left = new TreeNode(7);
        root.right.left.right = new TreeNode(8);
        System.out.println(serializedBinaryTree(root));
    }
    

    输出结果:

    output:
    1!2!4!#!#!#!3!5!7!#!#!8!#!#!6!#!#!
    

    其中 # 表示节点为空,! 是分隔符。

    实现反序列化:

    public static TreeNode deSerializedBinaryTree(String tree) {
        String[] s = tree.split("!");
        Queue<TreeNode> queue = new LinkedList<>();
        for (int i = 0; i < s.length; i++) {
            TreeNode node = null;
            if (s[i].equals("#")) {
                node = new TreeNode(Integer.MIN_VALUE);
            } else {
                node = new TreeNode(Integer.parseInt(s[i]));
            }
            queue.offer(node);
        }
        TreeNode root = queue.poll();
        makeTree(root, queue);
        return root;
    }
    
    private static void makeTree(TreeNode root, Queue<TreeNode> queue) {
        if (root == null || root.val == Integer.MIN_VALUE) {
            return;
        }
        root.left = queue.poll();
        makeTree(root.left, queue);
        root.right = queue.poll();
        makeTree(root.right, queue);
    }
    

    测试,借用了此前实现序列化的树反序列化:

    public static void main(String[] args) {
        // 构建二叉树
        TreeNode root = new TreeNode(1);
        root.left = new TreeNode(2);
        root.right = new TreeNode(3);
        root.left.left = new TreeNode(4);
        root.right.left = new TreeNode(5);
        root.right.right = new TreeNode(6);
        root.right.left.left = new TreeNode(7);
        root.right.left.right = new TreeNode(8);
        System.out.println(serializedBinaryTree(root));
    
        String s = serializedBinaryTree(root);
        TreeNode tree = deSerializedBinaryTree(s);
        printTree(tree);
    }
    

    输出,借用了此前二叉树按层遍历打印的方法,其中空节点用整型的最小值代替:

    		    1
             /     
            2		3
           /       / 
          4       5   6
                 / 
                7   8  
    
    output:
    1 
    2 3 
    4 -2147483648 5 6 
    -2147483648 -2147483648 7 8 -2147483648 -2147483648 
    -2147483648 -2147483648 -2147483648 -2147483648 
    
  • 相关阅读:
    dp学习(六)
    dp学习(五)
    电子效应
    元素周期表
    铝、元素三角与焰色反应
    化学能与原电池:知识预习
    有机化学与生产生活
    乙烯和苯:知识预习
    有机物基础和甲烷:知识预习
    解析api的json
  • 原文地址:https://www.cnblogs.com/chenxianbin/p/11941631.html
Copyright © 2020-2023  润新知