C++二叉树前中后序遍历(递归&非递归)统一代码格式
统一下二叉树的代码格式,递归和非递归都统一格式,方便记忆管理。
三种递归格式:
前序遍历:
void PreOrder(TreeNode* root, vector<int>&path)
{
if (root)
{
path.emplace_back(root->val);
PreOrder(root->left, path);
PreOrder(root->right, path);
}
}
中序遍历:
void InOrder(TreeNode* root, vector<int>& path)
{
if (root)
{
InOrder(root->left, path);
path.emplace_back(root->val);
InOrder(root->right, path);
}
}
后序遍历:
void PostOrder(TreeNode* root, vector<int>& path)
{
if (root)
{
PostOrder(root->left, path);
PostOrder(root->right, path);
path.emplace_back(root->val);
}
}
三种递归遍历不用多解释。
三种非递归格式:
前序遍历:
void PreOrderCycle(TreeNode* root, vector<int>& path)
{
stack<pair<TreeNode*, bool>> s;
s.emplace(make_pair(root, false));
bool visited;
while (!s.empty())
{
root = s.top().first;
visited = s.top().second;
s.pop();
if (root == NULL)
continue;
if (visited)
path.emplace_back(root->val);
else
{
s.emplace(make_pair(root->right, false));
s.emplace(make_pair(root->left, false));
s.emplace(make_pair(root, true));
}
}
}
中序遍历:
void InOrderCycle(TreeNode* root, vector<int>& path)
{
stack<pair<TreeNode*, bool>> s;
s.emplace(make_pair(root, false));
bool visited;
while (!s.empty())
{
root = s.top().first;
visited = s.top().second;
s.pop();
if (root == NULL)
continue;
if (visited)
path.emplace_back(root->val);
else
{
s.emplace(make_pair(root->right, false));
s.emplace(make_pair(root, true));
s.emplace(make_pair(root->left, false));
}
}
}
后序遍历:
void PostOrderCycle(TreeNode* root, vector<int>& path)
{
stack<pair<TreeNode*, bool>> s;
s.emplace(make_pair(root, false));
bool visited;
while (!s.empty())
{
root = s.top().first;
visited = s.top().second;
s.pop();
if (root == NULL)
continue;
if (visited)
path.emplace_back(root->val);
else
{
s.emplace(make_pair(root, true));
s.emplace(make_pair(root->right, false));
s.emplace(make_pair(root->left, false));
}
}
}
以上三种遍历实现代码行数一模一样,如同递归遍历一样,只有三行核心代码的先后顺序有区别。
解释下三种非递归遍历(以下图举例):

对二叉树而言,将每个框内结点集都看做一个局部,那么局部有 A,A B C,B D E,D,E,C F G,F,G 并且可以发现每个结点元素都是相邻的两个局部的重合结点。
算法流程:
1 每个结点元素都是相邻的两个局部的重合结点。对一个局部排好序后,通过取出一个重合结点过渡到与之相邻的局部进行新的局部排序。
2 用栈来保证局部顺序(排在前面的后入栈,排在后面的先入栈,保证局部元素出栈的顺序一定正确)
3 通过栈顶元素过渡到新局部的排序,对新局部的排序会导致该结点再次入栈,
4 当栈顶出现已完成过渡使命的结点时,就可以彻底出栈输出了,新栈顶元素会继续完成新局部的过渡
5 当所有结点都完成了过渡使命了,就全部出栈了。
参考:
https://www.jianshu.com/p/49c8cfd07410
C++二叉树前中后序遍历(递归&非递归)统一代码格式的更多相关文章
- [C++] 非递归实现前中后序遍历二叉树
目录 前置技能 需求描述 binarytree.h 具体实现 binarytree.cpp main.cpp 网上代码一搜一大片,大同小异咯. 书上的函数实现代码甚至更胜一筹,而且抄一遍就能用,唯一问 ...
- 二叉树前中后/层次遍历的递归与非递归形式(c++)
/* 二叉树前中后/层次遍历的递归与非递归形式 */ //*************** void preOrder1(BinaryTreeNode* pRoot) { if(pRoot==NULL) ...
- Binary Tree Traversal 二叉树的前中后序遍历
[抄题]:二叉树前序遍历 [思维问题]: 不会递归.三要素:下定义.拆分问题(eg root-root.left).终止条件 [一句话思路]: 节点非空时往左移,否则新取一个点 再往右移. [输入量] ...
- POJ 2255 Tree Recovery && Ulm Local 1997 Tree Recovery (二叉树的前中后序遍历)
链接:poj.org/problem?id=2255 本文链接:http://www.cnblogs.com/Ash-ly/p/5463375.html 题意: 分别给你一个二叉树的前序遍历序列和中序 ...
- 数据结构-C语言递归实现树的前中后序遍历
#include <stdio.h> #include <stdlib.h> typedef struct tree { int number ; struct tree *l ...
- C++实现对树的创建和前中后序遍历
#include<iostream>#include<stdio.h> using namespace std; class BitNode{ public: char dat ...
- LeetCode 145 二叉树的后序遍历(非递归)
题目: 给定一个二叉树,返回它的 后序 遍历. 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [3,2,1] 进阶: 递归算法很简单,你可以通过迭代算法完成吗? 解题思路: 1 ...
- 飘逸的python - 极简的二叉树前中后序通杀函数
对于任一结点.能够按某种次序运行三个操作: 訪问结点本身(N) 遍历该结点的左子树(L) 遍历该结点的右子树(R) 用来表示顺序,即,前序NLR/中序LNR/后序LRN. 以下我们用namedtupl ...
- 前中后序递归遍历树的体会 with Python
前序:跟->左->右 中序:左->根->右 后序:左>右->根 采用递归遍历时,编译器/解释器负责将递归函数调用过程压入栈并保护现场,在不同位置处理根节点即可实现不 ...
随机推荐
- 【HANA系列】SAP HANA SQL IFNULL和NULLIF用法与区别
公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[HANA系列]SAP HANA SQL IFN ...
- 《机器学习实战(基于scikit-learn和TensorFlow)》第七章内容学习心得
本章主要讲述了“集成学习”和“随机森林”两个方面. 重点关注:bagging/pasting.boosting.stacking三个方法. 首先,提出一个思想,如果想提升预测的准确率,一个很好的方法就 ...
- Mac 每次重启终端后配置的不生效.需要重新source
Mac 每次都要执行source ~/.bash_profile 配置的环境变量才生效 自己在 ~/.bash_profile 中配置环境变量, 可是每次重启终端后配置的不生效.需要重新执行 : $s ...
- vue项目自动构建工具1.0,支持多页面构建
该工具适用于超多项目开发,每个项目不用都安装依赖,所有依赖都安装在ffk命令项目中,对于多分支拉到本地进行开发,亦有益处.对于多页面开发,也是相当便利,不用手动撸entry和plugin. git: ...
- 理解twisted中的reactor和deferred(二)
Deferred可以添加多个回调函数,每个回调函数的结果作为下一个回调函数的参数 代码实例(可在pycharm中运行,摘自 https://twistedmatrix.com/documents/cu ...
- python的文件读写操作
文件读写 本文转自廖雪峰老师的教程https://www.liaoxuefeng.com/wiki/1016959663602400/1017607179232640 读写文件是最常见的IO操作.Py ...
- python 安装PostgreSQL 模块:psycopg2
官方资料:http://www.psycopg.org/psycopg/docs/ 安装: yum -y install python-psycopg2 (安装的版本可能是2.0) pip insta ...
- 【hash表】图书管理
[哈希和哈希表]图书管理 题目描述 图书管理是一件十分繁杂的工作,在一个图书馆中每天都会有许多新书加入.为了更方便的管理图书(以便于帮助想要借书的客人快速查找他们是否有他们所需要的书),我们需要设计一 ...
- python基础知识0-2
# !/usr/bin/env python # 提示输入用户名和密码 # 验证用户名和密码# 如果错误,则输出用户名或密码错误# 如果成功,则输出 欢迎,XXX! import ge ...
- MySQL中的数据库对象
1.数据库中一般包含下列对象 表.约束.索引.触发器.序列.视图: 可以使用图形用户界面或通过显式执行语句来创建这些数据库对象.用于创建这些数据库对象的语句称为“数据定义语言”(DDL),它们通常以关 ...