算法 - 二叉树

二叉树

二叉树按层遍历打印

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

		    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 
posted @ 2019-11-27 13:32  学习趁早  阅读(112)  评论(0编辑  收藏  举报