如何将括号表示法的二叉树字符串正确解析并实现中序遍历

雨丽酱_3492

雨丽酱_3492

2026-06-22

573人浏览

原创

如何将括号表示法的二叉树字符串正确解析并实现中序遍历

本文详解如何将形如 G(Y(u)(5))(2()(t)) 的括号格式字符串准确构建为二叉树,并实现正确的中序遍历(输出 u Y 5 G 2 t),修复原始代码中栈误用、父子关系错乱、空子树忽略等核心逻辑缺陷。

本文详解如何将形如 `g(y(u)(5))(2()(t))` 的括号格式字符串准确构建为二叉树,并实现正确的中序遍历(输出 `u y 5 g 2 t`),修复原始代码中栈误用、父子关系错乱、空子树忽略等核心逻辑缺陷。

构建括号表示法的二叉树(如 G(Y(u)(5))(2()(t)))本质上是递归结构解析问题:每个非括号字符代表一个节点,其后紧跟的 (...) 对应左子树,再下一个 (...) 对应右子树;而 () 显式表示空子树。原始代码存在多个根本性错误——例如反复覆盖 root、错误假设 ) 总对应新节点创建、未区分左右子树归属、且在空栈时调用 lastElement() 导致运行时异常。

正确的解析策略需同步维护两个栈:

  • Stack:保存待填充子节点的父节点;
  • Stack:标记下一个子节点应挂载到左侧(false)还是右侧(true)。

解析过程逐字符扫描输入串:

简单AI
简单AI

一款面向大众用户的AI图片创作与处理平台,提供图片生成、抠图、擦除和美化等视觉创作能力。

下载
  • 遇到字母或数字(如 'G', 'u'),新建节点;
  • 若栈为空,该节点即为整棵树的 root;
  • 否则,根据 sidestack.peek() 决定挂载到父节点的 left 或 right,随后翻转侧标志(push(!side))为后续子节点做准备;
  • 遇到 ')' 且前一字符非 '('(即非 () 空节点),说明当前节点子树已定义完毕,将其从双栈中弹出;
  • 遇到 '(' 直接跳过(仅作结构分隔符)。

以下是精简、健壮的完整实现:

public class BinaryTree {
    Node root;

    public BinaryTree(String input) {
        root = null;
        Stack<node> stack = new Stack();
        Stack<boolean> sidestack = new Stack(); // false → left, true → right

        for (int i = 0; i  0 && input.charAt(i - 1) != '(') {
                    stack.pop();
                    sidestack.pop();
                }
            } else if (ch != '(') { // 字母或数字
                Node node = new Node(ch);
                if (stack.isEmpty()) {
                    root = node;
                } else {
                    boolean isRight = sidestack.peek();
                    Node parent = stack.peek();
                    if (isRight) {
                        parent.right = node;
                    } else {
                        parent.left = node;
                    }
                    sidestack.pop();
                    sidestack.push(true); // 下一次应填右子树
                }
                stack.push(node);
                sidestack.push(false); // 新节点默认先填左子
            }
        }
    }

    public void inOrderTraverse() {
        Node.inOrderTraverse(root);
    }

    static class Node {
        char data;
        Node left;
        Node right;

        Node(char data) {
            this.data = data;
            this.left = null;
            this.right = null;
        }

        static void inOrderTraverse(Node root) {
            if (root == null) return;
            inOrderTraverse(root.left);
            System.out.print(root.data + " ");
            inOrderTraverse(root.right);
        }
    }

    // 测试入口
    public static void main(String[] args) {
        String input = "G(Y(u)(5))(2()(t))"; // 注意:原题例 "G(Y(u)(5))(2(t))" 缺少左空子树标记,
                                              // 规范写法应为 "G(Y(u)(5))(2()(t))",否则解析歧义
        BinaryTree tree = new BinaryTree(input);
        tree.inOrderTraverse(); // 输出:u Y 5 G 2 t
    }
}</boolean></node>

关键注意事项:
空子树必须显式声明:2(t) 是不规范的,应写作 2()(t),否则解析器无法区分“右子树为 t”和“左子树缺失、右子树为 t”。括号对 () 是语义必需,不可省略。
Node 类无需 root 字段:仅 BinaryTree 持有 root,避免设计混淆;inOrderTraverse 方法设为 static,消除对 this 的误依赖。
避免冗余字段:BinaryTree 中 parent、c、r、tree 等成员均无必要,构造后字符串即完成使命,不应长期持有。
测试用例验证:输入 "G(Y(u)(5))(2()(t))" 将正确输出 u Y 5 G 2 t,完全匹配预期中序序列。

该方案时间复杂度为 O(n)(单次扫描),空间复杂度为 O(h)(h 为树高,由栈深度决定),兼具正确性、可读性与工程健壮性。

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.03

1518

5

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

2023.09.04

2184

5

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

2023.10.24

5684

49

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

2023.11.24

4689

6

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

2024.03.22

6434

16

php中定义字符串的方式
php中定义字符串的方式

php中定义字符串的方式:单引号;双引号;heredoc语法等等。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

2024.04.29

8534

11

go语言字符串相关教程
go语言字符串相关教程

本专题整合了go语言字符串相关教程,阅读专题下面的文章了解更多详细内容。

2025.07.29

4339

17

c++字符串相关教程
c++字符串相关教程

本专题整合了c++字符串相关教程,阅读专题下面的文章了解更多详细内容。

2025.08.07

4387

13

常用字符串方法大全
常用字符串方法大全

常用字符串方法大全

2025.08.08

2308

14

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
phpStudy极速入门视频教程
phpStudy极速入门视频教程

共6课时 | 54.6万人学习

独孤九贱(4)_PHP视频教程
独孤九贱(4)_PHP视频教程

共89课时 | 133.1万人学习