94-144-145.二叉树的前中后序遍历
递归遍历
cppclass Solution{ public: # 输入输出 void pretraversal(TreeNode* cur, vector<int>& vec){ # 终止条件 if(cur==NULL) return ; # 其中一步 vec.push_back(cur->val); pretraversal(cur->left, vec); pretraversal(cur->right, vec); } void midtraversal(TreeNode* cur, vector<int>& vec){ if(cur==NULL) return ; midtraversal(cur->left, vec); vec.push_back(cur->val); midtraversal(cur->right, vec); } void lttraversal(TreeNode* cur, vector<int>& vec){ if(cur==NULL) return ; lttraversal(cur->left, vec); lttraversal(cur->right, vec); vec.push_back(cur->val); } vector<int> preorderTraversal(TreeNode* root){ vector<int> preans; vector<int> midans; vector<int> ltans; pretraversal(root, preans); midtraversal(root, midans); lttraversal(root, ltans); return preans; } };迭代遍历
cppclass Solution{ public: vector<int> preorderTraversal(TreeNode* root){ stack<TreeNode*> st; vector<int> ans; if(root==NULL) return ans; st.push(root); while(!st.empty()){ TreeNode* t=st.top(); st.pop(); ans.push_back(t->val); if(t->right) st.push(t->right); if(t->left) st.push(t->left); } return ans; } vector<int> inorderTraversal(TreeNode* root){ vector<int> ans; stack<TreeNode*> st; TreeNode* cur=root; while(cur!=NULL || !st.empty()){ if(cur!=NULL){ st.push(cur); cur=cur->left; }else{ cur=st.top(); st.pop(); ans.push_back(cur->val); cur=cur->right; } } return ans; } vector<int> postorderTraversal(TreeNode* root){ vector<int> ans; stack<TreeNode*> st; if(root==NULL) return ans; TreeNode* cur=root; st.push(root); while(!st.empty()){ TreeNode* t=st.top(); st.pop(); ans.push_back(t->val); if(t->left) st.push(t->left); if(t->right) st.push(t->right); } reverse(ans.begin(),ans.end()); return ans; } };迭代的统一写法:
cppclass Solution{ public: vector<int> preorderTraversal(TreeNode* root){ vector<int> ans; stack<TreeNode*> st; if(root!=NULL) st.push(root); while(!st.empty()){ TreeNode* t=st.top(); if(t!=NULL){ st.pop(); if(t->right) st.push(t->right); if(t->left) st.push(t->left); st.push(t); st.push(NULL); }else{ st.pop(); t=st.top(); st.pop(); ans.push_back(t->val); } } return ans; } vector<int> inorderTraversal(TreeNode* root){ vector<int> ans; stack<TreeNode*> st; if(root!=NULL) st.push(root); while(!st.empty()){ TreeNode* t=st.top(); if(t!=NULL){ st.pop(); if(t->right) st.push(t->right); st.push(t); st.push(NULL); if(t->left) st.push(t->left); }else{ st.pop(); t=st.top(); st.pop(); ans.push_back(t->val); } } return ans; } vector<int> postorderTraversal(TreeNode* root){ vector<int> ans; stack<TreeNode*> st; if(root!=NULL) st.push(root); while(!st.empty()){ TreeNode* t=st.top(); if(t!=NULL){ st.pop(); st.push(t); st.push(NULL); if(t->right) st.push(t->right); if(t->left) st.push(t->left); }else{ st.pop(); t=st.top(); st.pop(); ans.push_back(t->val); } } return ans; } };其他:
(1)递归思想:
a.确定递归函数的参数 和返回值(输入和输出)
b.确定终止条件(走到哪停)
c.确定单层递归逻辑(自己走其中一步)
(2)递归转迭代,通常第一步应该先执行一半 ,再写循环,不然容易搞不清楚
比如前序遍历的迭代方法,就是在循环前先把头节点入栈,然后循环 <节点出栈--左右节点入栈> 的过程
(3)前序和后序的迭代是类似的,中序的迭代循环写的很精妙,涉及或条件、循环变量
a.或条件while(cur!=NULL || !st.empty())
当 <cur指针不为空> 或者 <栈不为空> 的时候循环,对应两种情况:操作 <树> 和操作 <栈> ,cur不为空就找左指针,cur为空且栈不为空就处理栈
b.循环变量cur
用cur的状态来判断进行到哪一步
(4)迭代的统一写法本质上是不同于之前,存在节点访问后再次入栈 的情况,要对这种情况的节点再入栈一个NULL空节点用于判断是否访问过
代码随想录刷题——二叉树篇(一)
s砚山s2025-11-01 22:59
相关推荐
机器人零零壹2 小时前
技术白皮书:iRobotCAM如何解决机器人激光切割应用中的核心难点,从CAD离线编程到双目视觉定位与轨迹自适应提升复杂空间曲线切割的精度、效率与柔性化水平布莱克6053 小时前
C/C++ 中变量的声明与定义:区别、联系与常见误区ZhengEnCi5 小时前
大模型的分类到底怎么分:从基础模型到推理模型、从通用到专用的完整图谱取名真是6 小时前
Python 算法知识点从基础到进阶罗西的思考6 小时前
【轻量化复刻大模型 / KIMI K3】KDA 模块交互式演示沫璃染墨8 小时前
从零入门计算机网络系列(十二):HTTP长连接与会话管理详解——从Connection到Cookie与Sessionnm_zfyjt8 小时前
信息流广告投放优化实践:线索成本评估模型与转化链路重构(家装建材案例)xiaoye-duck9 小时前
《C++ 项目:手写大模型接入 SDK》DeepSeek接口设计(下):流式响应实现和测试w_zero_one9 小时前
算法--构造其实防守也摸鱼10 小时前
信创安全竞赛知识总结与题库