统一下二叉树的代码格式,递归和非递归都统一格式,方便记忆管理。

三种递归格式:

前序遍历:

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++二叉树前中后序遍历(递归&非递归)统一代码格式的更多相关文章

  1. [C++] 非递归实现前中后序遍历二叉树

    目录 前置技能 需求描述 binarytree.h 具体实现 binarytree.cpp main.cpp 网上代码一搜一大片,大同小异咯. 书上的函数实现代码甚至更胜一筹,而且抄一遍就能用,唯一问 ...

  2. 二叉树前中后/层次遍历的递归与非递归形式(c++)

    /* 二叉树前中后/层次遍历的递归与非递归形式 */ //*************** void preOrder1(BinaryTreeNode* pRoot) { if(pRoot==NULL) ...

  3. Binary Tree Traversal 二叉树的前中后序遍历

    [抄题]:二叉树前序遍历 [思维问题]: 不会递归.三要素:下定义.拆分问题(eg root-root.left).终止条件 [一句话思路]: 节点非空时往左移,否则新取一个点 再往右移. [输入量] ...

  4. POJ 2255 Tree Recovery && Ulm Local 1997 Tree Recovery (二叉树的前中后序遍历)

    链接:poj.org/problem?id=2255 本文链接:http://www.cnblogs.com/Ash-ly/p/5463375.html 题意: 分别给你一个二叉树的前序遍历序列和中序 ...

  5. 数据结构-C语言递归实现树的前中后序遍历

    #include <stdio.h> #include <stdlib.h> typedef struct tree { int number ; struct tree *l ...

  6. C++实现对树的创建和前中后序遍历

    #include<iostream>#include<stdio.h> using namespace std; class BitNode{ public: char dat ...

  7. LeetCode 145 二叉树的后序遍历(非递归)

    题目: 给定一个二叉树,返回它的 后序 遍历. 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [3,2,1] 进阶: 递归算法很简单,你可以通过迭代算法完成吗? 解题思路: 1 ...

  8. 飘逸的python - 极简的二叉树前中后序通杀函数

    对于任一结点.能够按某种次序运行三个操作: 訪问结点本身(N) 遍历该结点的左子树(L) 遍历该结点的右子树(R) 用来表示顺序,即,前序NLR/中序LNR/后序LRN. 以下我们用namedtupl ...

  9. 前中后序递归遍历树的体会 with Python

    前序:跟->左->右 中序:左->根->右 后序:左>右->根 采用递归遍历时,编译器/解释器负责将递归函数调用过程压入栈并保护现场,在不同位置处理根节点即可实现不 ...

随机推荐

  1. 安装php的sphinx扩展模块

    转自 http://blog.csdn.net/fenglailea/article/details/38115821 首先你必须已经安装过了sphinx 如何安装sphinx请看:http://bl ...

  2. 1. Linux基本操作和基本命令

    常用快捷键: Ctrl + d : 结束符 Ctrl + c : 中断前台进程 Ctrl + z : 将前台进程停止掉   创建终端: 创建终端标签:Ctrl + Shift + t; 切换标签: A ...

  3. document.documentElement.clientHeight 和 document.body.clientHeight

    document.documentElement.clientHeight 和 document.body.clientHeight 介绍 在进行一些网页效果处理的时候,经常碰到document.do ...

  4. C# WindowService 动态修改服务名

    serviceInstaller1中可以设置服务名,描述等 在实际情况中,我们可能需要将Service多开来达到我们的目的,但是安装两次以上会有错误提示,因为服务名已经重复了,这个时候,我们需要动态改 ...

  5. Java学习笔记-Java中的常用类

    Java中有很多类是很常用的,此处列举System,Runtime,Date,Calendar,Math System System:类中的方法和属性都是静态的 字段摘要 static PrintSt ...

  6. ZOJ Problem Set - 1003

    1.翻译参考 http://www.cnblogs.com/woodfish1988/archive/2006/11/10/556926.html 2.代码参考 http://www.cnblogs. ...

  7. Appendix 2- Lebesgue integration and Reimann integration

    Lebesgue integration and Reimann integration: Reimann: Split up the axis into equal intervals, then ...

  8. PostgreSQL 循环导出schema的脚本

    需要备份的schema列表 $ cat need_backup_schema.txt pipeline_na_16q3_v4 pipeline_na_16q4_v8 pipeline_na_16q4_ ...

  9. springboot整合servlet

    在idea新建项目 这个是pom.xml文件需要添加的依赖包 <properties> <java.version>1.8</java.version> </ ...

  10. Python之Web前端Ajax

    Ajax: 对于WEB应用程序:用户浏览器发送请求,服务器接收并处理请求,然后返回结果,往往返回就是字符串(HTML),浏览器将字符串(HTML)渲染并显示浏览器上. 1.传统的Web应用 一个简单操 ...