28. 二叉树遍历

news2025/1/4 19:20:43

题目描述
根据给定的二叉树结构描述字符串,输出该二叉树按照中序遍历结果字符串。中序遍历顺序为:左子树,根结点,右子树。

输入描述
由大小写字母、左右大括号、逗号组成的字符串:
1、字母代表一个节点值,左右括号内包含该节点的子节点。
2、左右子节点使用逗号分隔,逗号前为空则表示左子节点为空,没有逗号则表示右子节点
为空。
3、二叉树节点数最大不超过100。
注:输入字符串格式是正确的,无需考虑格式错误的情况。

输出描述
输出一个字符串,为二叉树中序遍历各节点值的拼接结果。

示例:
输入:a{b{d,e{g,h{,I}}},c{f}}
输出:dbgehiafc

一、问题分析

首先读题,仔细看描述中的内容,发现需求是

1.根据给定的二叉树结构描述字符串,输出该二叉树按照中序遍历结果字符串。

2.中序遍历顺序为:左子树,根节点,右子树。

3.输入描述:由大小写字母、左右大括号、逗号组成的字符串:

(1)字母代表一个节点值,左右括号内包含该节点的子节点。

(2)左右子节点使用逗号分隔,逗号前为空则表示左子节点为空,没有逗号则表示右子节点为空

(3)二叉树节点数最大不超过100

注:输入字符串格式是正确的,无需考虑格式错误的情况。

4.输出描述:输出一个字符串,为二叉树中序遍历各节点值的拼接结果。

二、解题思路

1.首先先确定题目的意思,

示例中的树应该是这样的

2.中序遍历(In - order Traversal)的意思是对于二叉树中的每个节点,先访问其左子树,然后访问根节点,最后访问右子树。这种方式可以按照从小到大(如果节点存储的数据是可比较大小的数值)或者某种特定的逻辑顺序来访问二叉树中的节点,具体顺序取决于节点值的排序和树的结构。

3.比如

这棵树的节点值分别为1(根节点)、2(左子节点)、3(右子节点)

按照中序遍历的规则,首先访问左子树,也就是节点2。然后访问根节点1,最后访问右子树的节点3。所以中序遍历的结果就是2、1、3。

4.再看一个稍微复杂一点的二叉树,节点值为4(根节点),左子树节点为2和1,右子树节点值为6和7,树的结构如下:

中序遍历过程:先访问左子树2,对于左子树2,又要先访问其左子树4,然后访问左子树的根节点(节点2)。接着访问整棵树根节点1。最后访问右子树3,对于右子树3,先访问其左子树(节点5),然后访问右子树的根节点(节点3)。

所以中序遍历的结果是4、2、1、5、3。

5.再来查看我们的示例中的树:

中序遍历过程:(从根节点a)先访问左子树b,对于左子树d又要先访问其左子树d,然后访问其根节点(b),然后访问b的右子树e,对于e我们又要先访问其左子树g,然后访问g的根节点e,然后访问e的右子树h,由于h没有左子树,我们访问完h之后还需要访问h的右子树I,然后我们访问b的根节点(a),然后我们访问a的右子树c,对于右子树c我们又要先访问c的左子树f,于是访问完f我们访问c

于是得到顺序dbgehiafc

6.如何读取二叉树?我们可以定义一个结构体用来表示二叉树的每一个节点

typedef struct TreeNode {

char val[20]; // 其中包含树的值

struct TreeNode* left; // 表示其左子树

struct TreeNode* right; // 表示其右子树

} TreeNode;

7.如何从输入构建二叉树?

比如示例中的输入是a{b{d, e{g,h{,I}}},c{f}}

// 我们一开始先接收整个树的根节点,然后是大括号,大括号中,逗号左边的是左子树,逗号右边的是右子树,如果逗号左边为空,证明左子树为空子树,如果没有都好,则证明右子树为空。

// 我们可以写一个buildTree函数,返回的是我们创建好的树的根节点,需要传入的参数是字符串s和s的索引值的指针(通过指针传递来更新位置)

TreeNode* buildTree(const char* s, int* idx) {

// 如果我们已经遍历到最后(遇到字符串结束符号)我们返回NULL;

if(s[*idx] == '\0') return NULL;

// 否则的话我们为树的结点分配内存,分配的内存大小就是树结点结构体的大小就可以了

TreeNode* root = (TreeNode*)malloc(sizeof(TreeNode));

// 我们定义一个temp用来存放节点名称,tempidx用来临时存放节点名的索引值

char temp[100];

int tempidx = 0;

while(isalpha(s[*idx])) {

temp[tempidx++] = s[*idx];

(*idx)++;

}

temp[tempidx] = '\0';

strcpy(root->val, temp);

// 之后我们为该节点添加左右子树,

// 如果遇到左大括号,证明我们下面可能跟了左子树,我们递归调用bulidTree函数如果没有左大括号证明我们可能没有子节点,返回

if(s[*idx] == '{') {

(*idx)++;

root->left = bulidTree(s, idx);

} else {

root->left = NULL;

return root;

}

// 如果遇到逗号,说明后面跟的是右子树

if(s[*idx] == ',') {

(*idx)++;

root->right = buildTree(s, idx);

} else {

root->right = NULL;

}

// 如果遇到右大括号,我们将索引值增加1,然后返回当前节点,

if(s[*idx] == '}') {

(*idx)++;

}

return root;

}

8.中序遍历二叉树函数

void inorderTraversal(TreeNode* root, char* result) {

if(root == NULL) return;

inorderTraversal(root->left, result);

strcat(result,root->val);

inorderTraversal(root->right,result);

}
9.我们声明一个函数用来释放二叉树占用的内存避免内存泄露

void freeTree(TreeNode* node) {

if(node == NULL) return;

freeTree(node->left);

freeTree(node->right);

free(node);

}

10.主程序

int main() {

char input[1000];

scanf("%s", input);

int idx = 0;

TreeNode* root = buildTree(input, &idx);

char result[1000] = {0};

inorderTraversal(root, result);

printf("%s\n", result);

freeTree(root);

return 0;

}

三、具体步骤

使用的语言是C

#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 首先我们定义树的节点结构
typedef struct TreeNode {
    char val[100];
    struct TreeNode* left;
    struct TreeNode* right;
} TreeNode;

TreeNode* buildTree(const char* s, int* idx) {
    // 如果我们读取到字符串末尾我们返回NULL
    if(s[*idx] == '\0') return NULL;
    // 为新的根节点分配内存
    TreeNode* root = (TreeNode*)malloc(sizeof(TreeNode));
    // 如果遇到字母,说明这是节点的名字
    if(isalpha(s[*idx])) {
        char temp[100];
        int tempidx = 0;
        while(isalpha(s[*idx])) {
            temp[tempidx++] = s[*idx];
            (*idx)++;
        }
        
        temp[tempidx] = '\0';
        strcpy(root->val, temp);
    }
    // 如果遇到左大括号,证明有子节点,否则我们认为没有左子节点
    if(s[*idx] == '{') {
        (*idx)++;
        root->left = buildTree(s, idx);
        //  printf("%s的左子树是%s\n", root->val, root->left->val);
        
    } else {
        // printf("%s的左子树是空\n", root->val);
        root->left = NULL;
        return root;
    }
    // 如果遇到逗号,说明有右子节点,否则我们认为没有右子节点
    if(s[*idx] == ',') {
        (*idx)++;
        if(isalpha(s[*idx])) {
            root->right = buildTree(s, idx);
        }
        // printf("%s的右子树是%s\n", root->val, root->right->val);

    } else {
        root->right = NULL;
    }
    // 如果遇到右大括号,证明左右子节点都已经构建好,我们将索引值向后移
    if(s[*idx] == '}') {
        (*idx)++;
    }

    return root;
}

void inorderTraversal(TreeNode* root, char* result) {
    if(root == NULL) return;
    inorderTraversal(root->left, result);
    strcat(result, root->val);
    inorderTraversal(root->right, result);
}

void freeTree(TreeNode* root) {
    if(root == NULL) return;
    freeTree(root->left);
    freeTree(root->right);
    free(root);
}
int main() {
    char input[1000];
    scanf("%s", input);
    int idx = 0;
    TreeNode* root = buildTree(input, &idx);
    char result[1000] = {0};
    inorderTraversal(root, result);
    printf("%s\n", result);
    freeTree(root);
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2269921.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Swift White Hawkstrider

Swift White Hawkstrider 迅捷白色陆行鸟 Swift White Hawkstrider - Item - 魔兽世界怀旧服TBC数据库_WOW2.43数据库_70级《燃烧的远征》数据库 Kaelthas Sunstrider (1) <Lord of the Blood Elves> 凯尔萨斯逐日者. 掉落 [80圣骑士][Alonsus-加丁][诺森德冒险补给品…

LeetCode算法题——有序数组的平方

题目描述 给你一个按非递减顺序排序的整数数组nums&#xff0c;返回每个数字的平方组成的新数组&#xff0c;要求也按非递减顺序排序。 题解 解法一&#xff1a;暴力解法 思路&#xff1a; 该题目可通过暴力解法解决&#xff0c;即利用for循环遍历数组&#xff0c;对数组每…

项目开发实践——基于SpringBoot+Vue3实现的在线考试系统(四)

文章目录 一、管理员角色功能实现1、添加教师功能实现1.1 页面设计1.2 前端功能实现1.3 后端功能实现1.4 效果展示2、教师管理功能实现2.1 页面设计2.2 前端功能实现2.3 后端功能实现2.3.1 后端查询接口实现2.3.2 后端编辑接口实现2.3.3 后端删除接口实现2.4 效果展示二、代码下…

DVWA靶场Brute Force (暴力破解) 漏洞low(低),medium(中等),high(高),impossible(不可能的)所有级别通关教程

目录 暴力破解low方法1方法2 mediumhighimpossible 暴力破解 暴力破解是一种尝试通过穷尽所有可能的选项来获取密码、密钥或其他安全凭证的攻击方法。它是一种简单但通常无效率的破解技术&#xff0c;适用于密码强度较弱的环境或当攻击者没有其他信息可供利用时。暴力破解的基…

基于feapder爬虫与flask前后端框架的天气数据可视化大屏

# 最近又到期末了&#xff0c;有需要的同学可以借鉴。 一、feapder爬虫 feapder是国产开发的新型爬虫框架&#xff0c;具有轻量且数据库操作方便、异常提醒等优秀特性。本次设计看来利用feapder进行爬虫操作&#xff0c;可以加快爬虫的速率&#xff0c;并且简化数据入库等操作…

抖音短视频矩阵系统源码开发技术解析

开发概览&#xff1a; 抖音短视频矩阵系统的构建基于一系列现代技术栈&#xff0c;主要包括VUE, Spring Boot和Django。本文档旨在为开发者提供关于短视频矩阵系统源代码的开发与部署指南。 技术框架分析&#xff1a; 前端技术选型&#xff1a; 对于前端界面的构建&#xf…

CentOS Stream 9 安装 JDK

安装前检查 java --version注&#xff1a;此时说明已安装过JDK&#xff0c;否则为未安装。如若已安装过JDK可以跳过安装步骤直接使用&#xff0c;或者先卸载已安装的JDK版本重新安装。 安装JDK 官网下载地址&#xff1a;https://www.oracle.com/java/technologies/downloads…

【git】git生成rsa公钥的方法

git生成rsa公钥的方法 一&#xff0c;简介二&#xff0c;操作方法三&#xff0c;总结 一&#xff0c;简介 在工作的过程中&#xff0c;经常需要生成rsa的密钥&#xff0c;然后提供给别人&#xff0c;然后别人给你开通代码下载权限。本文介绍如何在本地生成rsa的密钥供参考。 …

Solon 加入 GitCode:助力国产 Java 应用开发新飞跃

在当今数字化快速发展的时代&#xff0c;Java 应用开发框架不断演进&#xff0c;开发者们始终在寻找更快、更小、更简单的解决方案。近期&#xff0c;Solon 正式加入 GitCode&#xff0c;为广大 Java 开发者带来全新的开发体验&#xff0c;尤其是在国产应用开发进程中&#xff…

如何通过深度学习提升大分辨率图像预测准确率?

随着科技的不断进步&#xff0c;图像处理在各个领域的应用日益广泛&#xff0c;特别是在医疗影像、卫星遥感、自动驾驶、安防监控等领域中&#xff0c;大分辨率图像的使用已经成为了一项不可或缺的技术。然而&#xff0c;大分辨率图像带来了巨大的计算和存储压力&#xff0c;同…

硬件基础知识笔记(2)——二级管、三极管、MOS管

Part 2 二级管、三极管、MOS管 1、二级管1.1肖特基二极管和硅二极管选型比较1.2到底是什么决定了二极管的最高工作频率&#xff1f;1.3二极管结电容和反向恢复时间都是怎么来的1.4肖特基二极管的工作原理1.5为什么要用肖特基二极管续流&#xff1f; 2、三极管2.1三极管工作原理…

操作系统论文导读(八):Schedulability analysis of sporadic tasks with multiple criticality specifications——具有多个

Schedulability analysis of sporadic tasks with multiple criticality specifications——具有多个关键性规范的零星任务的可调度性分析 目录 一、论文核心思想 二、基本定义 2.1 关键性指标 2.2 任务及相关参数定义 2.3 几个基础定义 三、可调度性分析 3.1 调度算法分…

word中文献引用[]符号的上下标格式修改

word中文献引用[]符号的上下标格式修改 百度网址 1、查找打开使用通配符&#xff0c;输入[[][0-9]{1,2}[]]&#xff0c;即可匹配所有的字[1],[12]这些字符&#xff0c;然后鼠标点击替换为的空白处&#xff0c;再点击特殊格式–>“字体”&#xff0c;选中上标&#xff0c;最…

在 ArcGIS Pro/GeoScene Pro 中设计专题地图的符号系统

原始 按颜色对面进行符号化 打开符号系统 选择主符号系统 选择字段及其计算方式 更改临界值</

_使用CLion的Vcpkg安装SDL2,添加至CMakelists时报错,编译报错

语言&#xff1a;C20 编译器&#xff1a;gcc 14.2 摘要&#xff1a;初次使用Vcpkg添加SDL2&#xff0c;出现CMakelists找不到错误、编译缺失main错误、运行失败错误。 CMakelists缺失错误&#xff1a; 使用CLion的Vcpkg安装SDL2时&#xff0c;按照指示把对应代码添加至CMakel…

解决Springboot整合Shiro+Redis退出登录后不清除缓存

解决Springboot整合ShiroRedis退出登录后不清除缓存 问题发现问题解决 问题发现 如果再使用缓存管理Shiro会话时&#xff0c;退出登录后缓存的数据应该清空。 依赖文件如下&#xff1a; <dependency><groupId>org.springframework.boot</groupId><arti…

2024-12-29-sklearn学习(26)模型选择与评估-交叉验证:评估估算器的表现 今夜偏知春气暖,虫声新透绿窗纱。

文章目录 sklearn学习(26) 模型选择与评估-交叉验证&#xff1a;评估估算器的表现26.1 计算交叉验证的指标26.1.1 cross_validate 函数和多度量评估26.1.2 通过交叉验证获取预测 26.2 交叉验证迭代器26.2.1 交叉验证迭代器–循环遍历数据26.2.1.1 K 折26.2.1.2 重复 K-折交叉验…

[TOTP]android kotlin实现 totp身份验证器 类似Google身份验证器

背景&#xff1a;自己或者公司用一些谷歌身份验证器或者microsoft身份验证器&#xff0c;下载来源不明&#xff0c;或者有广告&#xff0c;使用不安全。于是自己写一个&#xff0c;安全放心使用。 代码已开源&#xff1a;shixiaotian/sxt-android-totp: android totp authenti…

Windows11 安卓子系统存储位置更改

文章目录 前言 更改存储位置总结 前言 Windows 11 的安卓子系统&#xff08;Windows Subsystem for Android, WSA&#xff09;为用户提供了在 PC 上运行安卓应用的便利&#xff0c;但默认情况下&#xff0c;WSA 的数据存储路径位于系统盘&#xff08;通常是 C 盘&#xff09;。…

家谱管理系统|Java|SSM|VUE| 前后端分离

【技术栈】 1⃣️&#xff1a;架构: B/S、MVC 2⃣️&#xff1a;系统环境&#xff1a;Windowsh/Mac 3⃣️&#xff1a;开发环境&#xff1a;IDEA、JDK1.8、Maven、Mysql5.7 4⃣️&#xff1a;技术栈&#xff1a;Java、Mysql、SSM、Mybatis-Plus、VUE、jquery,html 5⃣️数据库…