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

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(使用前将#替换为@)

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

  • 为什么会出现此异常 FileItemStream$ItemSkippedException?

    在 gwt Web 应用程序中 我必须发送一个文件和附加的一些参数 在服务器端 try ServletFileUpload upload new ServletFileUpload FileItemIterator iterator upl
  • 具有默认值的 Java JAX-RS 自定义参数

    假设我有这个 这只是一个示例 GET Path value address Produces application json public Response getAddress QueryParam user User user 用户是
  • 我在socket上设置了超时,发现这个值不能大于21

    我在socket上设置了超时 该值小于21秒才有效 21秒后发现超时还是21秒 public static void main String args SimpleDateFormat sdf new SimpleDateFormat yy
  • JavaFX 图像未在舞台中显示

    我尝试了很多次 尝试了很多方法 但都无法让自己的形象在舞台上如我所愿 我认为这可能与java寻找资源的路径有关 但我不确定 因为我刚刚开始使用视觉库 在本例中为JavaFX 这是我的目录结构 MyProject assets img myI
  • 无法在类对象的 ArrayList 中存储值。 (代码已编辑)

    这基本上是一个 Java 代码转换器 它涉及一个 GUI 让用户输入类类型 名称和方法 为了存储值 我创建了一个类VirtualClass与ArrayList
  • 防止 Spring Boot 注册 Spring Security 过滤器之一

    我想禁用安全链中的 Spring Security 过滤器之一 我已经看到了防止 Spring Boot 注册 servlet 过滤器 https stackoverflow com questions 28421966 prevent s
  • URL.setURLStreamHandlerFactory

    我正在使用带有嵌入式 Jetty 的可执行 jar 开发一个 Web 应用程序 我的jar包含一个依赖jar jar in jar 我参考了JarRsrcLoader and RsrcURLStreamHandlerFactory由 Ecl
  • 在哪里可以获得有关 Java FitNesse 和 Slim 的一些教程? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • Java、Oracle 中索引处缺少 IN 或 OUT 参数:: 1 错误

    您好 我使用 Netbeans 8 0 2 和 Oracle 11g Express Edition 在 JSF 2 2 中编写了一个图书馆管理系统 我有几个名为 书籍 借阅者 等的页面 以及数据库中一些名为相同名称的表 我的问题是这样的
  • 哪个 Swing 布局管理器可以获得我想要的布局?

    我正在尝试按照这个模型制作一个基本的登录菜单 我决定将整个菜单放入 JPanel 中 以便在连接成功后我可以切换到另一个面板 所以我决定使用 Borderlayout 将标题放在北区 将连接按钮放在南区 我将边框布局的中心本身设置为面板 我
  • 请参阅 Java EE eclipse 调试中的 POST 参数

    我在调试 Java EE 方面没有经验 我更像是一个 javascript 人 我需要查看哪些 HTTP POST 参数到达服务器端 我在表单将其操作指向的 jsp 文件中放置了一个断点 现在我在调试变量窗口中找不到 POST 内容 他们在
  • 字符串池可以包含两个具有相同值的字符串吗? [复制]

    这个问题在这里已经有答案了 字符串池可以包含两个具有相同值的字符串吗 String str abc String str1 new String abc Will the second statement with new operator
  • JTable 和 JScrollpane 大小的问题

    我有一个JScrollPane with a JTable在里面 在里面JTable我最初有 3 行 稍后添加行 默认JTable我的 3 行很难看 因为JScrollPane calls getPreferredScrollableVie
  • 容器中的 JVM 计算处理器错误?

    最近我又做了一些研究 偶然发现了这一点 在向 OpenJDK 团队抱怨之前 我想看看是否有其他人观察到这一点 或者不同意我的结论 因此 众所周知 JVM 长期以来忽略了应用于 cgroup 的内存限制 众所周知 现在从 Java 8 更新某
  • 改变for循环的顺序?

    我遇到一种情况 我需要根据用户输入以不同的顺序循环遍历 xyz 坐标 所以我是 3D 空间中的一个区域 然后是一组像这样的 for 循环 for int x 0 x lt build getWidth x for int y 0 y lt
  • 为什么我的代码会产生错误:该语句没有返回结果集[重复]

    这个问题在这里已经有答案了 我正在从 Microsoft SQL Server Studio 执行以下查询 该查询工作正常并显示结果 SELECT INTO temp table FROM md criteria join WHERE us
  • 使用 secp256r1 曲线和 SHA256 算法生成 ECDSA 签名 - BouncyCastle

    我正在尝试使用带有 secp256r1 曲线 P256 的 ECDSA 和用于消息哈希的 SHA256 算法生成签名 我也在使用 Bouncy Castle 库 下面的代码 public class MyTest param args pu
  • 如何解决 PDFBox 没有 unicode 映射错误?

    我有一个现有的 PDF 文件 我想使用 python 脚本将其转换为 Excel 文件 目前正在使用PDFBox 但是存在多个类似以下错误 org apache pdfbox pdmodel font PDType0Font toUnico
  • 摩尔斯电码 至 英语

    我现在的问题是让 摩尔斯电码转英语 正常工作 将英语转换为莫尔斯电码的第一部分工作正常 我知道以前已经有人问过这个问题 但我不知道我做错了什么 我知道我需要在某个地方进行拆分 但我只是不确定将其放在代码中的何处 现在 莫尔斯电码到英语的部分
  • 防止Java实例化的正确方法[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi

随机推荐