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

三种递归格式:

前序遍历:

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. iOS开发嵌套ReactNative页面

    最近使用ReactNative做项目,有信心今天目标把ReactNative框架掌握,所以自己从每个知识点学习提高自己吧...... 步骤如下: 一.创建依赖包文件(package.json): Re ...

  2. rsync同步脚本

    #!/bin/bash export LANG=C date=`date +%Y-%m-%d-%H%M` red=`echo -e "\033[0;31m"` blue=`echo ...

  3. HTML5 DOM 新增数据类型

    HTML5 DOM 新增数据类型 前言 相对于HTML4当中的DOM,在HTML5中的DOM,新增了很多复杂数据类型,为实际的应用提供了便捷的操作. 在HTML5 DOM中,新增了如下的内容: HTM ...

  4. 小米6使用charles抓包https

    1. 下载charles 地址: https://zhubangbang.com/charles-crack-version-free-download-and-install-tutorial.ht ...

  5. 一、linux基础命令

    一. 常用系统工作命令 1.echo 命令 ​ echo命令用于在终端输出字符串或者变量提取后的值 ​ echo $SHELL 2.date命令 ​ date命令用于显示及设置系统的时间或者日期 参数 ...

  6. C#中Math方法总结

    名称  说明      E  表示自然对数的底,它由常数 e 指定.    PI  表示圆的周长与其直径的比值,它通过常数 π 指定. Abs  已重载.返回指定数字的绝对值.      Acos   ...

  7. 【图像处理】DVR H.264视频编码基本知识

    视频编码技术基本是由ISO/IEC制定的MPEG-x和ITU-T制定的H.26x两大系列视频编码国际标准的推出.从H.261视频编码建议,到 H.262/3.MPEG-1/2/4等都有一个共同的不断追 ...

  8. NDK学习笔记-JNI开发流程

    JNI(Java Native Interface)Java本地化接口,Java调用C/C++,C/C++调用Java的一套API接口 实现步骤 在Java源文件中编写native方法 public ...

  9. JavaScript控制输入框只能输入中文,英文和数字的组合,其他字符不能输入的校验

    if(!/^[A-Za-z0-9\u4e00-\u9fa5]+/.test(value)){ alert('不能输入非法字符') }

  10. merge效率

    测试merge效率   测试说明: MERGE是oracle提供的一种特殊的sql语法,非常适用于数据同步场景,即: (把A表数据插到B表,如果B表存在相同主键的记录则使用A表数据对B表进行更新) 数 ...