打印二叉树

2023-10-27

摘要

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

打印二叉树 的相关文章

随机推荐

  • 辟谣、催债、倒闭.....2018年后,将再无创业黄金期!

    导读 上下游没钱了 信贷机构没钱了 风险投资人也没钱了 中小企业成本和资金压力大 企业违约 到期没法还债 非银行金融机构爆雷 大量出问题 股市非理性下滑 所有人进入新一轮升级性迷茫 由于各项成本的抬升 未来 不缺钱也不缺资源的头部企业将变得
  • Spark 基础教程

    Spark是基于内存计算的大数据并行计算框架 可用于构建大型的 低延迟的数据分析应用程序 Spark特点 运行速度快 Spark使用先进的DAG Directed Acyclic Graph 有向无环图 执行引擎 以支持循环数据流与内存计算
  • 软件发布之版本命名

    简介软件的版本命名与编号 img src http blog csdn net ppbage aggbug 747919 aspx width 1 height 1
  • unity--触屏游戏中如何判断点击的位置的左右&触屏游戏中如何判断点击的位置的左右&通过反转对象,让左侧运动的动画应用于右侧运动&通过代码改变图层覆盖顺序(Sorting Layer)

    文章目录 触屏游戏中如何判断点击的位置的左右 使用获取到的触碰坐标来进行左右移动 通过反转对象 让左侧运动的动画应用于右侧运动 通过代码改变图层覆盖顺序 Sorting Layer 触屏游戏中如何判断点击的位置的左右 我们先要有一个可以反馈
  • osg学习(四十)osg::Viewer的realize创建窗体的几种方式

    能够根据屏幕数 创建不同位置的窗口 void Viewer realize 在某一个屏幕上创建无边框窗口 在某一个屏幕上创建正常窗口 在所有屏幕上创建正常窗口 一个窗口 窗口位置可以跨屏幕 osgViewer SingleWindow实现
  • promise笔记

    promise笔记 以下笔记主要参考axios官网里的promise教程 写在这里方便以后复习或者查找 Promise javascript info 可以通过这个链接进行学习 更加详细 文章目录 promise笔记 1 介绍 2 基本语法
  • 将字符串格式的时间格式化

    时间格式化 param Number date 时间戳 param DateString fmt 时间格式 dateFormat yyyy MM dd hh mm ss S gt 2016 03 12 20 13 32 232 return
  • Object.create 以及 Object.setPrototypeOf

    第一部分 Object crate 方法是es5中的关于原型的方法 这个方法会使用指定的原型对象以及属性去创建一个新的对象 语法 Object create proto propertiesObjecy 参数 proto 必须的 一个对象
  • 云计算简介

    什么是 云 迁移至云端 在云中运行 在云中存储 从云端访问 当今时代 似乎一切都在 云 中进行 但是 云 究竟是一个什么样的概念 简单来说 云就是互联网连接的另一端 你可以从云端访问各种应用程序和服务 也可以在云端安全存储你的数据 云 之所
  • 扫描二维码 跳转到小程序指定页面

    注意 必须发布代码之后才能使用扫描二维码跳转 规则 1 二维码规则 填写你要生成的二维码的链接 2 小程序功能页面 要跳转的小程序的页面 3 测试链接 也填同样的链接 4 将上面的链接生成一个二维码 测试链接 5 通过微信扫描这个二维码跳转
  • 安装Apex库

    在Linux系统下安装Apex库 1 安装流程 按顺序使用如下命令 git clone https github com NVIDIA apex cd apex pip3 install v no cache dir 注意 不能直接使用pi
  • iOS 多线程

    1 怎么用GCD实现多读单写 dispatch barrier async 2 ios系统为我们提供的几种多程序技术各自的特点是怎样的 GCD 实现一些简单的线程同步 子线程的分派 包括一些类似于多读单写 nsoperation 比如adn
  • 2022年最佳的9种逆向工程工具[持续更新]

    逆向是复杂的 然而 软件开发人员经常在面临一项具有挑战性的任务时转向反向工程 增强软件安全性 使软件与第三方组件兼容 维护遗留代码 等等 在本文中 我们将描述我们的软件逆向程序在工作中所依赖的主要工具 并展示如何使用这些工具的实际示例 本文
  • python输入多组测试数据_python ddt数据驱动实例代码分享

    python ddt数据驱动最简实例 在接口自动化测试中 往往一个接口的用例需要考虑 正确的 错误的 异常的 边界值等诸多情况 然后你需要写很多个同样代码 参数不同的用例 如果测试接口很多 不但需要写大量的代码 测试数据和代码柔合在一起 可
  • STM32基于HAL库带FreeRTOS系统的Freemodbus移植

    STM32基于HAL库移植带FreeRTOS系统的Freemodbus移植 移植前提 下载所需源码 可能的win10 IAR设置 从站注意定义寄存器数量大小 效果查询报文 效果回复报文 移植事件 定时器 串口 事件移植 串口移植 定时器移植
  • Electron+React+Antd将网页打包成应用程序完整步骤(electron-builder (搭建热更新) 或 electron-packager(不搭建热更新))

    一 创建React项目 ps 由于写的时候没注意 包安装有的用npm有的用yarn 大家统一用一个就行 尽量不要使用cnpm ps 源码地址 git clone https github com Aug Sunrise electron t
  • 【mysql】mysql表分区、索引的性能测试

    概述 mysql分区表概述 google搜索一下 RANGE COLUMNS partitioning 主要测试mysql分区表的性能 load 500w 条记录 大约在10min左右 batch insert 1 9w条记录 没建立索引
  • 小米升级后开机显示无服务器,小米手机升级后无法开机解决方法

    方法1 刷机 在关机的状态下 进rec中双清 音量上键和开机键按住出来第一个mi画面全部松手 再按住音量加 然后在双清 然后关机音量下键和开机键同时摁住进入fastboot模式 出现米兔修机器人界面 线刷开发版刷机包和教程可以到http w
  • vue3中keep-alive和vue-router的结合使用

    vue3中keep alive和vue router的结合使用 前言 代码 一 为何要使用keep alive 二 vue2中使用keep alive 将 router view 组件包含于 keep alive 即可 三 vue3中使用k
  • 打印二叉树

    摘要 https wylu github io posts 91f36751 本文将使用两种展示方式打印一颗二叉树 效果如下 8 12 14 20 15 13 10 11 9 4 6 7 5 2 3 1 20