当前位置: 首页 > news >正文

二叉树遍历--(前 中 后 层序)

1.前序遍历

前序遍历顺序 先访问根节点再左子树 最后右子树  

根->左->右

#include <iostream>
#include <stack>struct TreeNode
{int val;TreeNode* left;TreeNode* right;TreeNode(int v):val(v),left(nullptr),right(nullptr){}
};//后序 左->右->根 先访问左子树 再访问右子树 最后访问根
//双栈法
//1.先实现 根->右->左 (先入左孩子)
//2.将该顺序入栈 再出栈变为 左->右->根
void PostT(TreeNode*root)
{if(root==nullptr)return;std::stack<TreeNode*> s1,s2;s1.push(root);while (!s1.empty()){auto top=s1.top();s1.pop();s2.push(top);if(top->left) s1.push(top->left);//先push左孩子if(top->right) s1.push(top->right);}while (!s2.empty()){auto top=s2.top();std::cout<<top->val<<" ";s2.pop();}std::cout<<std::endl;
}int main() {TreeNode* root = new TreeNode(1);root->left = new TreeNode(2);root->right = new TreeNode(3);root->left->left = new TreeNode(4);root->left->right = new TreeNode(5);PostT(root);return 0;
}

1.先定义一个栈,栈是先进后出。每新进一个节点,先输出值 再把它的左右孩子压入到栈中。先压入哪个孩子?先压右孩子 再压左孩子。这样出栈时先出左孩子 符合根->左->右顺序

2.后序遍历

后序遍历顺序 左->右->根 左右子树访问完 最后访问根节点

#include <iostream>
#include <stack>struct TreeNode
{int val;TreeNode* left;TreeNode* right;TreeNode(int v):val(v),left(nullptr),right(nullptr){}
};//后序 左->右->根 先访问左子树 再访问右子树 最后访问根
//双栈法
//1.先实现 根->右->左 (先入左孩子)
//2.将该顺序入栈 再出栈变为 左->右->根
void PostT(TreeNode*root)
{if(root==nullptr)return;std::stack<TreeNode*> s1,s2;s1.push(root);while (!s1.empty()){auto top=s1.top();s1.pop();s2.push(top);if(top->left) s1.push(top->left);//先push左孩子if(top->right) s1.push(top->right);}while (!s2.empty()){auto top=s2.top();std::cout<<top->val<<" ";s2.pop();}std::cout<<std::endl;
}int main() {TreeNode* root = new TreeNode(1);root->left = new TreeNode(2);root->right = new TreeNode(3);root->left->left = new TreeNode(4);root->left->right = new TreeNode(5);PostT(root);return 0;
}

前序 根->左->右    后序 左->右->根

我们可以用双栈法来解决,用一个栈来完成前序遍历 并把遍历的值存入另一个栈了

这样 前序 根左右 出栈-> 右左根 但和后序不一样怎么办?

把前序压入左右子树的顺序该一下变为 先压左 再压右  =>  根->右->左

这样出栈就可以变为 后序 左->右->根

3.中序遍历

先访问完左子树 再根 最后右子树 

左->根->右

我们先循环把左孩子压入栈 直到没有左孩子,左孩子为空相当于左子树遍历完了,按照顺序我们就可以输出根节点值(此时栈顶就是要输出的节点),最后访问右子树。再以右孩子为根节点 继续循环压入左孩子... 

#include <iostream>
#include <stack>struct TreeNode
{int val;TreeNode* left;TreeNode* right;TreeNode(int v):val(v),left(nullptr),right(nullptr){}
};
//中序 左->根->右
void InT(TreeNode* root) 
{if(root==nullptr)return;std::stack<TreeNode*> s;TreeNode* cur=root;while(cur||!s.empty()){//把根/左孩子全入栈while(cur){s.push(cur);cur=cur->left;}//此时栈顶元素 为树的最左节点 它没有左孩子 //中序左 根 右  左为空 直接输出根auto top=s.top();std::cout<<top->val<<" ";s.pop();//再继续找右孩子的最左节点cur=top->right;}std::cout<<std::endl;
}
int main() {TreeNode* root = new TreeNode(1);root->left = new TreeNode(2);root->right = new TreeNode(3);root->left->left = new TreeNode(4);root->left->right = new TreeNode(5);InT(root);return 0;
}

4.层序遍历

自顶向下 从左到右,进行输出。

#include <iostream>
#include <queue>
struct TreeNode
{int val;TreeNode* left;TreeNode* right;TreeNode(int v):val(v),left(nullptr),right(nullptr){}
};
void LevelT(TreeNode*root)
{if(root==nullptr)return;std::queue<TreeNode*> q;q.push(root);while(!q.empty()){int tmp=q.size();while(tmp){auto cur=q.front();std::cout<<cur->val<<" ";q.pop();tmp--;if(cur->left)q.push(cur->left);if(cur->right)q.push(cur->right);}std::cout<<std::endl;}
}

用一个队列存下一层需要输出的节点,每pop一个节点 就把它的左右孩子push入队,直到栈为空。可以向上面用一个tmp记录当前层需要pop的节点,每一行打印一层。

遍历方式顺序定义实现思路关键点/数据结构
前序遍历根 → 左 → 右栈:根入栈 → 先右后左入栈stack<TreeNode*>
中序遍历左 → 根 → 右栈:一路左压栈 → 出栈访问 → 处理右stack<TreeNode*>
后序遍历左 → 右 → 根双栈:根 → 左 → 右 入辅助栈,翻转为后序stack<TreeNode*> s1, s2
层序遍历一层一层 → 从左到右队列:每层记录当前层节点个数 → 入队左右孩子queue<TreeNode*>

http://www.xdnf.cn/news/551683.html

相关文章:

  • 【lvgl9】使用keyboard和textarea实现密码数字输入界面
  • Git 克隆子分支
  • 本地ip如何映射到外网?借助端口映射软件把内网地址给别人用
  • Jetson Agx Orin平台JP5.1.4-R35.6.0版本VI recover导致内核崩溃问题(有官方patch)
  • uni-app项目从0-1基础架构搭建全流程
  • Nextcloud与Google就安卓文件访问权限展开博弈
  • 从代码学习深度学习 - 预训练word2vec PyTorch版
  • NebulaGraph学习笔记-SessionPool之Session not existed
  • 五、central cache的设计
  • 多环境回测模拟不同市场条件下的策略表现
  • CSS专题之常见布局
  • 设备全生命周期管理:从采购到报废的数字化闭环方案
  • Varlet UI-Material Design风格Vue 3框架移动端组件库
  • SUI批量转账几种方法介绍
  • 构建AI时代的大数据基础设施-MaxCompute多模态数据处理最佳实践
  • 人工智能+:职业价值的重构与技能升级
  • LSM Tree算法原理
  • [特殊字符]车牌识别相机,到底用在哪?
  • 芯片分享之AD976性能介绍
  • NVM 安装与配置指南
  • Python中使用CUDA/GPU的方式比较
  • GMSL:汽车里的音视频传输
  • Python 包管理工具uv依赖分组概念解析
  • 瑞莎星睿 O6 (Radxa Orion O6)-ubuntu24.04-ROS2 运行深度估计模型
  • 数据分析_主播考核指标体系搭建
  • C++学习:六个月从基础到就业——多线程编程:互斥量与锁
  • Git 删除大文件教程
  • 如果用户点击微博的关注图标,但是app上面没有反应,应该怎么排查这个问题?
  • 集成飞书多维表格
  • 详解MySQL 的 binlog,redo log,undo log