打印二叉树

摘要

https://wylu.github.io/posts/91f36751/

本文将使用两种展示方式打印一颗二叉树,效果如下:

8
├── 12
│   ├── 14
│   │   ├── 20
│   │   │   └── 15
│   │   └── 13
│   └── 10
│       ├── 11
│       └── 9
└── 4
    ├── 6
    │   ├── 7
    │   └── 5
    └── 2
        ├── 3
        └── 1
                 /----- 20
                 |       \----- 15
         /----- 14
         |       \----- 13
 /----- 12
 |       |       /----- 11
 |       \----- 10
 |               \----- 9
8
 |               /----- 7
 |       /----- 6
 |       |       \----- 5
 \----- 4
         |       /----- 3
         \----- 2
                 \----- 1

构建二叉树

为了方便测试,我们需要构建一颗二叉树,这里使用前序遍历序列和中序遍历序列来重建二叉树。

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

    public TreeNode(int x) {
        val = x;
    }
}
/**
 * @File    :   Tree.java
 * @Time    :   2020/03/23 17:46:15
 * @Author  :   wylu
 * @Version :   1.0
 * @Contact :   15wylu@gmail.com
 * @License :   (C)Copyright 2020, wylu-CHINA-SHENZHEN
 * @Desc    :
 */
public class Tree {
    private static TreeNode mk(int[] pre, int[] in,
                               int startPre, int endPre,
                               int startIn, int endIn) {
        if (startPre == endPre) {
            return null;
        }
        TreeNode root = new TreeNode(pre[startPre]);
        // 中序遍历序列根结点索引
        int idx = startIn;
        while (idx < endIn && in[idx] != root.val) {
            idx++;
        }

        // 左子树序列长度
        int llen = idx - startIn;
        // 左右子树序列中点(右子树序列起始点)
        int mpre = startPre + 1 + llen;
        root.left = mk(pre, in, startPre + 1, mpre, startIn, idx - 1);
        root.right = mk(pre, in, mpre, endPre, idx + 1, endIn);
        return root;
    }

    /**
     * 利用前序遍历序列和中序遍历序列构建一颗二叉树
     * 
     * @param pre 前序遍历序列
     * @param in  中序遍历序列
     * @return
     */
    public static TreeNode mkTree(int[] pre, int[] in) {
        if (pre == null || in == null || pre.length == 0 || pre.length != in.length) {
            return null;
        }
        return mk(pre, in, 0, pre.length, 0, in.length);
    }
}

调用示例:

public static void main(String[] args) {
    // Case 1
    int[] pre = {1, 2, 4, 7, 3, 5, 6, 8};
    int[] in = {4, 7, 2, 1, 5, 3, 8, 6};
    TreeNode root = Tree.mkTree(pre, in);
}

二叉树打印类

/**
 * @File : TreePrinter.java
 * @Time : 2020/03/23 17:47:57
 * @Author : wylu
 * @Version : 1.0
 * @Contact : 15wylu@gmail.com
 * @License : (C)Copyright 2020, wylu-CHINA-SHENZHEN
 * @Desc :
 */
public class TreePrinter {
    private static void linuxStyle(TreeNode root, StringBuilder sb, String prefix, String childPrefix) {
        if (root == null) {
            return;
        }
        sb.append(prefix);
        sb.append(root.val);
        sb.append("\n");
        linuxStyle(root.right, sb, childPrefix + "├── ", childPrefix + "│   ");
        linuxStyle(root.left, sb, childPrefix + "└── ", childPrefix + "    ");
    }

    public static StringBuilder getLinuxStyle(TreeNode root) {
        StringBuilder sb = new StringBuilder();
        linuxStyle(root, sb, "", "");
        return sb;
    }

    /**
     * z
     * ├── c
     * │ ├── a
     * │ └── b
     * └── d
     *
     * @param root
     */
    public static void prtLinuxStyle(TreeNode root) {
        System.out.println(getLinuxStyle(root).toString());
    }

    public static StringBuilder horizontalStyle(TreeNode root, StringBuilder sb) {
        if (root.right != null) {
            horizontalStyle(root.right, sb, true, "");
        }
        sb.append(root.val).append("\n");
        if (root.left != null) {
            horizontalStyle(root.left, sb, false, "");
        }
        return sb;
    }

    private static void horizontalStyle(TreeNode root, StringBuilder sb, boolean isRight,
            String indent) {
        if (root.right != null) {
            horizontalStyle(root.right, sb, true, indent + (isRight ? "        " : " |      "));
        }
        sb.append(indent);
        sb.append(isRight ? " /" : " \\");
        sb.append("----- ");
        sb.append(root.val).append("\n");
        if (root.left != null) {
            horizontalStyle(root.left, sb, false, indent + (isRight ? " |      " : "        "));
        }
    }

    /**
     *                 /----- 20
     *                 |       \----- 15
     *         /----- 14
     *         |       \----- 13
     * /----- 12
     * |       |       /----- 11
     * |       \----- 10
     * |               \----- 9
     * 8
     * |              /----- 7
     * |      /----- 6
     * |      |       \----- 5
     * \----- 4
     *        |       /----- 3
     *        \----- 2
     *                \----- 1
     *
     * @param root
     */
    public static void prtHorizontalStyle(TreeNode root) {
        System.out.println(horizontalStyle(root, new StringBuilder()).toString());
    }

    public static void main(String[] args) {
        // Case 1
        int[] pre = {1, 2, 4, 7, 3, 5, 6, 8};
        int[] in = {4, 7, 2, 1, 5, 3, 8, 6};
        TreeNode root = Tree.mkTree(pre, in);
        TreePrinter.prtLinuxStyle(root);
        TreePrinter.prtHorizontalStyle(root);

        // Case 2
        pre = new int[] {8, 4, 2, 1, 3, 6, 5, 7, 12, 10, 9, 11, 14, 13, 20, 15};
        in = new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 20};
        root = Tree.mkTree(pre, in);
        TreePrinter.prtLinuxStyle(root);
        TreePrinter.prtHorizontalStyle(root);
    }
}

References

https://stackoverflow.com/questions/4965335/how-to-print-binary-tree-diagram

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值