C++ 怎么实现二叉树 C++节点定义与前中后序遍历【数据结构】
技术百科
冰火之心
发布时间:2026-01-26
浏览: 次 C++二叉树节点应定义为struct,含int val及初始化为nullptr的left、right指针,并提供无参、单参、三参构造函数;前序/中序/后序递归遍历均需先判空,仅处理顺序不同;非递归遍历用stack模拟,中序需持续向左入栈再弹出转向右;建树时禁用局部变量地址,须用new或智能指针确保生命周期安全。
怎么定义 C++ 二叉树节点(带构造函数和 nullptr 安全)
直接用 struct 最简洁,关键是要默认初始化指针为 nullptr,避免野指针;同时加一个带参构造函数,方便快速创建节点。
-
val存数据,类型按需改(比如int或string) -
left和right必须初始化为nullptr,否则递归遍历时可能崩溃 - 不写析构函数也没问题——除非你用了
new分配子节点且需要手动释放(一般推荐栈上创建或智能指针)
struct TreeNode {
int val;
TreeNode* left;
TreeNode* right;
TreeNode() : val(0), left(nullptr), right(nullptr) {}
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
TreeNode(int x, TreeNode* l, TreeNode* r) : val(x), left(l), right(r) {}
};前序/中序/后序遍历的递归写法(统一模板,只差顺序)
三者结构完全一致:都是“访问当前 → 递归左 → 递归右”,区别只在打印/处理 root->val 的位置。记住口诀:“前根左右、中左根右、后左右根”。
- 前序:处理
root→traverse(root->left)→traverse(root->right) - 中序:递归左 → 处理
root→ 递归右(BST 中序即升序) - 后序:递归左 → 递归右 → 处理
root(适合删树、求高度等依赖子树结果的场景) - 所有递归函数必须判空:
if (!root) return;,否则访问nullptr->val直接段错误
void preorder(TreeNode* root) {
if (!root) return;
cout << root->val << " "; // 前序:根最先
preorder(root->left);
preorder(root->right);
}非递归遍历怎么写(用 stack 模拟调用栈)
递归本质是系统用栈保存现场,自己模拟时核心是「什么时候 push、什么时候 pop、什么时候记录结果」。前序最简单,中序次之,后序最难——别硬记,用「标记法」统一处理。
- 前序非递归:先压右再压左(因为栈是后进先出,要保证左先被处理)
- 中序非递归:一路向左入栈,到底后弹出并转向右子树
- 后序推荐「标记法」:每个节点压栈两次,第一次带
false标记(表示未处理子树),第二次带true(可输出)。遇到true才记录值 - 注意:非递归代码里
stack不够,得用stack或自定义结构体>
// 中序非递归示例
void inorder_iterative(TreeNode* root) {
stack st;
TreeNode* cur = root;
while (cur || !st.empty()) {
while (cur) {
st.push(cur);
cur = cur->left; // 一直压左
}
cur = st.top(); st.pop();
cout << cur->val << " "; // 此时左子树已完,访问根
cur = cur->right; // 转向右
}
} 为什么建树时容易崩?常见空指针陷阱
新手常在构建测试树时崩溃,根本原因不是遍历逻辑错,而是节点指针没连对,或者连了局部变量地址。
- 别这样写:
TreeNode node(1); TreeNode* root = &node;——node是栈变量,函数返回后地址失效 - 正确方式:用
new(记得delete)或更推荐用智能指针unique_ptr - 手动连子节点时,漏写
root->left = ...或写成root->left->left = ...(中间
为
nullptr时解引用必崩) - 调试技巧:遍历前加一句
assert(root != nullptr);,或用if (!root) { cout
后序遍历的左右子树依赖性最强,一旦某个 left 或 right 是悬空指针,它会第一个暴露问题。
# 都是
# 第一个
# 弹出
# 什么时候
# 一句
# 数据结构
# 递归
# 递归函数
# c++
# String
# if
# int
# 区别
# 指针
# 构造函数
# 为什么
# 栈
# node
# delete
# 析构函数
# 结构体
# Struct
# 空指针
# 遍历
# 局部变量
# 子树
# 升序
# 二叉树
相关栏目:
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
AI推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
SEO优化<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
技术百科<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
谷歌推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
百度推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
网络营销<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
案例网站<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
精选文章<?muma echo $count; ?>
】
相关推荐
- Win11怎么设置组合键快捷方式_Windows1
- c++的static关键字有什么用 静态变量和静态
- Win11怎么快速锁屏_Win11一键锁屏快捷键W
- windows系统如何安装cab更新补丁_wind
- 如何在 Go 中比较自定义的数组类型(如 [20]
- 如何使用Golang处理网络超时错误_Golang
- Win10如何卸载微软拼音输入法 Win10只保留
- php485函数怎么捕获异常_php485错误处理
- 如何在 Laravel 中通过嵌套关联关系进行 o
- Go语言中slice追加操作的底层共享机制详解
- Python文本编码与解码_跨平台解析说明【指导】
- 如何在Golang中理解指针比较_Golang地址
- 如何诊断并终止卡死的 multiprocessin
- 如何在Golang中处理JSON字段缺失_Gola
- 如何使用Golang指针与结构体结合_修改结构体内
- 如何使用Golang实现Web表单数据绑定_自动映
- Win11怎么更改系统语言_Win11中文语言包下
- Windows10如何更改计算机工作组_Win10
- Linux怎么禁止Root用户远程登录_Linux
- 使用类变量定义字符串常量时如何实现类型安全的 Li
- Windows10如何查看蓝屏日志_Win10使用
- Go 中实现 Python urllib.quot
- Win11怎么恢复误删照片_Win11数据恢复工具
- Windows如何拦截2345弹窗广告_Windo
- 如何在JavaScript中动态拼接PHP的bas
- php怎么下载安装后无法解析php文件_服务器配置
- PHP的FastAdmin架构适合二次开发吗_特点
- mac怎么打开终端_MAC终端Terminal使用
- 如何在同包不同文件中正确引用 Go 结构体
- Win11怎么清理C盘虚拟内存_Win11清理虚拟
- 如何使用Golang实现微服务事件驱动_使用消息总
- Win11怎么查看电脑配置_Win11硬件配置详细
- c++20的std::format怎么用 比pri
- php控制舵机角度怎么调_php发送pwm信号控制
- Win11怎么设置右键刷新选项_Windows11
- Win11搜索不到蓝牙耳机怎么办 Win11蓝牙驱
- Python如何创建带属性的XML节点
- Python异步编程高级项目教程_asyncio协
- Windows 10怎么录屏_Windows 10
- Win11怎么设置ip地址_Windows 11手
- PHP怎么接收前端传的时间戳_处理时间戳参数转换技
- Win11如何设置环境变量 Win11添加和修改系
- 如何在Golang中使用内置函数_Golangle
- Win11怎么关闭系统声音_Win11系统提示音静
- c# Task.ConfigureAwait(tr
- windows 10专注助手怎么关闭_window
- c++怎么实现大文件的分块读写_c++ 文件指针s
- Mac如何调整Dock栏大小和位置_Mac程序坞个
- VSC怎么配置PHP的Xdebug_远程调试设置步
- Python配置文件操作教程_JSONINIYAM


QQ客服