按照层次遍历结果打印完全二叉树

2024-01-04

按照层次遍历结果打印完全二叉树

在这里插入图片描述

按照推论结果:

  • l 层首个节点位置 2 h-l - 1
  • l 层节点间距: 2 h-l+1 - 1

编码实现

 public static<E> void print(BinaryTree<E> tree) {
        List<List<Node<E>>> levelNodeList = levelOrderTraversal(tree);
        int height = levelNodeList.size();
        for (int level = 1; level <= height; level++) {
            List<Node<E>> nodelist = levelNodeList.get(level - 1);
            // 打印首个节点
            int firstNodePosition = (int) Math.pow(2, (height - level)) - 1;
            System.out.print(getBlankSpace(firstNodePosition) + nodelist.get(0).element);

            int separation = (int)Math.pow(2, (height-level+1)) - 1;
            String separationBlankSpace = getBlankSpace(separation);
            for (int i = 1; i < nodelist.size(); i++) {
                // 打印中间节点
                System.out.print(separationBlankSpace + nodelist.get(i).element);
            }
            System.out.println();
        }
    }

    public static<E>List<List<Node<E>>> levelOrderTraversal(BinaryTree<E> tree) {
        Queue<Node<E>> queue = new LinkedList<>();
        queue.offer(tree.root);
        List<List<Node<E>>> result = new ArrayList<>();
        while (!queue.isEmpty()) {
            // 此时队列的容量就是当前层的节点个数
            int levelSize = queue.size();
            ArrayList<Node<E>> levelNodes = new ArrayList<>();
            for (int i = 0; i < levelSize; i++) {
                Node<E> node = queue.poll();
                levelNodes.add(node);

                if (node.left != null) {
                    queue.offer(node.left);
                }

                if (node.right!= null) {
                    queue.offer(node.right);
                }
            }

            result.add(levelNodes);
        }

        return result;
    }

    private static String getBlankSpace(int n) {
        StringBuilder builder = new StringBuilder();
        while (n > 0) {
            builder.append(" ");
            n--;
        }

        return builder.toString();
    }

打印效果

在这里插入图片描述

似乎更预想的不一样,猜测是因为 像 11,12这种两位数实际占了两个字符,导致的。将所有数都改成 1:

在这里插入图片描述

显示完美。

将空格改为 \t

在这里插入图片描述

显示还是有问题。考虑将最后一层间距修改为 2,通过双 \t 控制显示格式

在这里插入图片描述

完整代码

package com.wy.algo.tree;

import cn.hutool.core.lang.Assert;

import java.util.*;
import java.util.stream.IntStream;
import java.util.stream.Stream;

/**
 * @author HelloWorld
 * @date 2024/1/2 18:32
 * @email helloworld.dng@gmail.com
 */
public class BinaryTree<E> {
    public static void main(String[] args) {
        BinaryTree<Integer> binaryTree = init(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
        //BinaryTree<Integer> binaryTree = init(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
        print(binaryTree);
    }
    Node<E> root;

    /**
     * @description 初始化二叉树(层次遍历)
     * @author HelloWorld
     * @create 2024/1/2 18:57
     * @param elements
     * @return com.wy.algo.tree.BinaryTree<E>
     */
    @SafeVarargs
    public static<E> BinaryTree<E> init(E... elements) {
        Assert.notEmpty(elements, "elements must not be empty");
        BinaryTree<E> tree = new BinaryTree<>();
        tree.root = new Node<>(elements[0]);

        Queue<Node<E>> queue = new LinkedList<>();
        queue.offer(tree.root);
        int index = 1;
        while (!queue.isEmpty()) {
            Node<E> node = queue.poll();
            if (index < elements.length) {
                node.left = new Node<>(elements[index]);
                queue.offer(node.left);
            }
            index++;

            if (index < elements.length) {
                node.right = new Node<>(elements[index]);
                queue.offer(node.right);
            }
            index++;
        }

        return tree;
    }


    public static<E> void print(BinaryTree<E> tree) {
        List<List<Node<E>>> levelNodeList = levelOrderTraversal(tree);
        int height = levelNodeList.size();
        for (int level = 1; level <= height; level++) {
            List<Node<E>> nodelist = levelNodeList.get(level - 1);
            // 打印首个节点
            int firstNodePosition = (int) Math.pow(2, (height - level)) - 1;
            System.out.print(getBlankSpace(firstNodePosition) + nodelist.get(0).element);
            // 优化显示效果,将间距修改为2
            int separation = (int)Math.pow(2, (height-level+1));
            String separationBlankSpace = getBlankSpace(separation);
            for (int i = 1; i < nodelist.size(); i++) {
                // 打印中间节点
                System.out.print(separationBlankSpace + nodelist.get(i).element);
            }
            System.out.println();
        }
    }

    public static<E>List<List<Node<E>>> levelOrderTraversal(BinaryTree<E> tree) {
        Queue<Node<E>> queue = new LinkedList<>();
        queue.offer(tree.root);
        List<List<Node<E>>> result = new ArrayList<>();
        while (!queue.isEmpty()) {
            // 此时队列的容量就是当前层的节点个数
            int levelSize = queue.size();
            ArrayList<Node<E>> levelNodes = new ArrayList<>();
            for (int i = 0; i < levelSize; i++) {
                Node<E> node = queue.poll();
                levelNodes.add(node);

                if (node.left != null) {
                    queue.offer(node.left);
                }

                if (node.right!= null) {
                    queue.offer(node.right);
                }
            }

            result.add(levelNodes);
        }

        return result;
    }

    private static String getBlankSpace(int n) {
        StringBuilder builder = new StringBuilder();
        while (n > 0) {
            builder.append("\t");
            n--;
        }

        return builder.toString();
    }


    /**
     * @description 根据节点个数,计算完全二叉树的高度
     * @author HelloWorld
     * @create 2024/1/2 19:48
     * @param nodeNums
     * @return int
     */
    public static int getHeight(int nodeNums) {
        int level = 1;
        while (!(Math.pow(2, level - 1) <= nodeNums && Math.pow(2, level) > nodeNums)) {
            level++;
        }

        return level;
    }


    static class Node<E> {
        E element;
        Node<E> left;
        Node<E> right;

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

按照层次遍历结果打印完全二叉树 的相关文章

  • java.lang.VerifyError:JVMVRFY012堆栈形状不一致;

    在 WAS 8 5 5 中部署 Maven 项目时出现以下错误 我在WAS中安装了JDK 1 6和1 7 错误500 org springframework web util NestedServletException 处理程序处理失败
  • 策略模式还是命令模式?

    假设我有一个金融交易列表 我需要针对这些交易执行一系列验证规则 一个例子是我有一笔购买产品的交易 但是首先我需要验证交易中的帐户是否有足够的可用资金 产品没有售完等 由于这些规则 交易将是标记为拒绝 并应指定错误代码 当然 我正在考虑用一个
  • 从文本文件中读取阿拉伯字符

    我完成了一个项目 在该项目中我读取了用记事本编写的文本文件 我的文本文件中的字符是阿拉伯语 文件编码类型是UTF 8 当在 Netbeans 7 0 1 中启动我的项目时 一切似乎都正常 但是当我将项目构建为 jar 文件时 字符以这种方式
  • Java 卡布局。多张卡中的一个组件

    一个组件 例如JLabel 在多张卡中使用CardLayout 目前看来该组件仅出现在它添加到的最后一张卡上 如果有办法做到这一点 我应该吗 这是不好的做法吗 或者有其他选择吗 你是对的 它只出现在 添加到的最后一张卡 中 但这与CardL
  • 运行 java -jar 时出现 java.lang.ClassNotFoundException

    我正在使用 ant 来构建我的build xml文件 它编译正常 但随后得到运行时java lang NoClassDefFoundError通过 运行生成的 jar 时java jar my jar jar 似乎这个问题出现了很多 但没有
  • 使用 Spring 控制器处理错误 404

    I use ExceptionHandler处理我的网络应用程序抛出的异常 在我的例子中我的应用程序返回JSON回应HTTP status用于对客户端的错误响应 但是 我正在尝试弄清楚如何处理error 404返回与处理的类似的 JSON
  • JavaFX使节点覆盖父节点边框颜色

    我有一个如下所示的节点 仅使用 css 我希望标签覆盖其父边框颜色 因此标签下方的边框颜色部分变得不可见 我用来制作这个边框的CSS代码 fx border color black fx border width 3 fx border r
  • 在grails控制器中识别ajax请求或浏览器请求

    我正在开发一个使用大量ajax的grails应用程序 如果请求是ajax调用 那么它应该给出响应 这部分正在工作 但是如果我在浏览器中输入URL 它应该带我到主页 索引页面而不是请求的页面 下面是ajax调用的示例gsp代码
  • 如何在 JPA 和 Hibernate 中将数据库生成的列值定义为只读字段?

    使用 MariaDB 10 2 可以定义日期时间的默认值 例如创建和最后修改 我应该如何将此列作为只读字段访问 因为这个值应该只在数据库的控制之下 并且不应该从代码中修改 但我想在代码中读取这个属性 这很简单 只需设置insertable
  • 插入时的 iBatis 判别器

    我有一个抽象类Example以及与之相伴的具体子类 我使用鉴别器来提取数据out数据库的 像这样
  • 在 java 中运行外部应用程序但不要等待它完成

    我正在用java编写一个应用程序 允许我运行其他应用程序 为此 我使用了 Process 类对象 但当我这样做时 应用程序会等待进程结束 然后再退出 有没有办法在 Java 中运行外部应用程序 但不等待它完成 public static v
  • Java 中 JButton 的击键/热键

    最初我使用 JMenu 并建立热键以使用加速器工作 它运行得很好 现在我想在 JButton 中实现相同的行为 但我陷入困境 这是我编写的代码 请分享您的想法 以便我可以走上正确的道路 import javax swing import j
  • BadPaddingException:无效的密文

    我需要一些帮助 因为这是我第一次编写加密代码 加密代码似乎工作正常 但解密会引发错误 我得到的错误是 de flexiprovider api exceptions BadPaddingException 无效的密文 in the 解密函数
  • Android:ANT 构建失败,并显示 google-play-services-lib:“解析为没有项目的 project.properties 文件的路径”

    我正在尝试使用 ANT 构建我的应用程序 但在包含 google play services lib 库项目后 我惨遭失败 Step 1 我在 project properties 文件中设置了对库项目的引用 android library
  • 如何从 JavaFX 中的另一个控制器类访问 UI 元素?

    我有一个使用 NetBeans 8 编写的 JavaFX Java 8 应用程序 没有SceneBuilder 我的应用程序有一个主窗口 该窗口有自己的 FXML 文件 primary fxml 和自己的控制器类 FXMLPrimaryCo
  • 让 Hibernate 和 SQL Server 与 VARCHAR 和 NVARCHAR 良好配合

    我目前正在大型数据库的某些表中启用 UTF 8 字符 这些表已经是 MS SQL 类型 NVARCHAR 此外 我还有几个使用 VARCHAR 的字段 Hibernate 与 JDBC 驱动程序的交互存在一个众所周知的问题 例如 参见在 h
  • Axis2 错误:要输出的文本中的空白字符 (0x4) 无效

    我创建了一个 Java 客户端 使用 Axis2 1 7 6 作为代码生成器与 SOAP Web 服务进行交互 问题在于客户端的某些输入抛出异常并显示以下消息 org apache axis2 AxisFault Invalid white
  • 如何使用自定义 JDK 构建 Jenkins 项目?

    我有一个常规的 Jenkins 实例 运行一些多分支管道 该实例在 JDK 11 上运行 因为 Jenkins 并不真正支持更高版本 没关系 但不好的是 我的所有管道似乎也都受到 Java 11 的限制 Jenkins 仅使用它自己也使用的
  • Java中单例的其他方式[重复]

    这个问题在这里已经有答案了 只是我在考虑编写单例类的其他方法 那么这个类是否被认为是单例类呢 public class MyClass static Myclass myclass static myclass new MyClass pr
  • java中void的作用是什么?

    返回类型 方法返回值的数据类型 如果方法不返回值 则返回 void http download oracle com javase tutorial java javaOO methods html http download oracle

随机推荐