一、二叉树的结构

二叉树的节点结构如下所示

template<typename T>
struct TreeNode
{T data;        //数据TreeNode* left;    //指向左孩子节点的指针TreeNode* right;   //指向右孩子节点的指针TreeNode(T dat, TreeNode* lft = nullptr, TreeNode* rig = nullptr):data(dat), left(lft), right(rig) {}
};

如下所示是一个二叉树,其中的每一个节点都是由上述TreeNode节点的一个具体对象。

图1

二、先序遍历、中序遍历、后序遍历

1、什么是先序遍历

先遍历根(父)节点、再遍历左节点、最后遍历右节点。

注意:这里说的遍历并不是行走。毕竟我们能够先取到的指针只有根节点指针,而如果想找一个节点,则一定要先找到它的根节点。这里的遍历指的是“介绍”这棵树的方式。通常来讲,我们是使用的打印的方式“介绍”一棵树的。

所以,先序遍历展开来讲是:如果一棵树上有根节点,则先输出根节点,再输出左孩子节点、最后输出右孩子节点。

例如,上述图1中的二叉树,先序遍历输出是:3、9、20、15、7

2、什么是中序遍历

先遍历输出左孩子节点,再遍历输出根节点,最后遍历输出右孩子节点。

例如,上述图1中的二叉树,中序遍历输出是:9、3、15、20、7

3、什么是后序遍历

先遍历输出左孩子节点,再遍历输出右孩子节点,最后遍历输出根节点。

例如,上述图1中的二叉树,后序遍历输出是:9、15、7、20、3

三、三种遍历的递归法

1、二叉树的递归序

首先,我们逐步分析二叉树的递归原理。我们取一个临时指针temp,来在二叉树上行进(根-左-右的顺序),则temp的指向顺序、即二叉树的递归序是:

--START

3(根节点)

9(找到3的左孩子、左子树根节点)

9(找9的左孩子,没有,则回到9)

9(找9的右孩子,没有,则回到9)

3(3的左子树遍历完毕,回到3)

20(3的右子树根节点)

15(20的左孩子)

15(15的左孩子,没有,回到15)

15(15的右孩子,没有,回到15)

20(20的左子树遍历完毕,回到20)

7(20的右孩子)

7(7的左孩子,没有,回到7)

7(7的右孩子,没有,回到7)

20(20的右子树遍历完毕,回到20)

3(3的右子树遍历完毕,回到3)

--END

其中的temp指向其实指的是

上述过程用代码实现如下:

void traversal(TreeNode* root) {//1)程序资源在root节点,判空if (nullptr == root){return;}//2)遍历左子树traversal(root->left);//左子树遍历完成,程序资源回到root节点//3)遍历右子树traversal(root->right);//右子树遍历完成,程序资源回到root节点return;
}

2、三种遍历的递归法实现

则我们可以看见规律。二叉树的递归序中,每一个节点都会被遍历3次。每个节点,当其作为root节点、左子树遍历完成、右子树遍历完成的时候,程序资源都会回到这个节点。

1)先序遍历的递归法

而先序遍历,则只要在第一次处于这个节点的时候进行输出即可。见下列代码:

void preorderTraversal(TreeNode* root) {//根节点为空,直接返回if (nullptr == root){return;}//1)输出cout << root->val << endl;//2)遍历左子树preorderTraversal(root->left);//3)遍历右子树preorderTraversal(root->right);return;
}

2)中序遍历的递归法

同理,中序遍历,只要在递归序的基础上,在第二次回到节点时输出即可。见下列代码:

void inorderTraversal(TreeNode* root) {//根节点为空,直接返回if (nullptr == root){return;}//1)遍历左子树inorderTraversal(root->left);//2)输出cout << root->val << endl;//3)遍历右子树inorderTraversal(root->right);return;
}

3)后序遍历的递归法

同理,后序遍历,只要在递归序的基础上,在第三次回到节点时输出即可。见下列代码:

void postorderTraversal(TreeNode* root) {//根节点为空,直接返回if (nullptr == root){return;}//1)遍历左子树postorderTraversal(root->left);//2)遍历右子树postorderTraversal(root->right);//3)输出cout << root->val << endl;return;
}

这样理解,二叉树的递归遍历法是不是非常简单了?

四、三种遍历的非递归法

任何递归函数都可以改成非递归函数。我们使用的递归法,其实是系统帮助我们压栈的一个过程。

1、分析解决方案

我们知道栈的特性是先入后出,如果按照一般遍历顺序根节点-左孩子-右孩子进行压栈,则和上述遍历顺序不符

2、三种遍历的非递归实现

1)先序遍历实现

算法步骤:

a、根节点进栈;

b、弹出并输出栈顶节点tp;

c、栈顶节点tp的左孩子进栈、右孩子进栈;

d、重复上述b、c;

代码实现:

void preorderTraversal(TreeNode* root) {if (nullptr == root){return;}stack< TreeNode*> mstack;mstack.push(root);while (!mstack.empty()){//打印栈顶节点TreeNode* tp = mstack.top();cout << tp->val << endl;//弹出节点mstack.pop();//右孩子节点压栈if (nullptr != tp->right){mstack.push(tp->right);}//左孩子节点压栈if (nullptr != tp->left){mstack.push(tp->left);}}return;
}

2)中序遍历实现

算法步骤:

a、从根节点开始,整棵树的左边界节点依次进栈;

b、弹出并输出栈顶节点tp;

c、栈顶节点tp的右子树左边界节点依次进栈

d、重复上述b、c;

代码实现:

void inorderTraversal(TreeNode* root) {TreeNode* tp = root;stack< TreeNode*> mstack;//弹出并输出栈顶节点,并对其右孩子节点压栈while (!mstack.empty() || nullptr != tp){//左边界节点依次进栈if (nullptr != tp){mstack.push(tp);tp = tp->left;}else{//获取栈顶节点指针tp = mstack.top();//输出cout << tp->val << endl;//弹出节点mstack.pop();//如果有右子树,右子树的左边界节点压栈tp = tp->right;}}return;
}

3)后序遍历实现

后序遍历即:左-右-根 的顺序。一般来说,我们一定会先行进到根节点,才能找到其左右子树。所以,我们可以想办法获得 根-右-左的节点遍历,再利用栈的特性反序输出。

算法步骤:

申请两个栈,s1,s2

a、根节点入栈s1;

b、弹出(不输出)栈顶节点tp,压入栈s2;

c、栈顶节点tp的左孩子、右孩子依次进栈s1;

d、重复上述b、c,直到栈s1为空,所有节点进入栈s2;

e、依次弹出并输出栈s2栈顶节点;

代码实现:

void postorderTraversal(TreeNode* root) {//根节点为空,直接返回if (nullptr == root){return;}//申请2个栈stack< TreeNode*> s1, s2;//根节点压入s1s1.push(root);while (!s1.empty()){TreeNode* tp = s1.top();s2.push(tp);s1.pop();if (nullptr != tp->left){s1.push(tp->left);}if (nullptr != tp->right){s1.push(tp->right);}}//依次弹出并输出s2节点while (!s2.empty()){cout << s2.top()->val << endl;s2.pop();}return;
}

二叉树的先序、中序、后序遍历C++相关推荐

  1. 二叉树的前、中、后序遍历

    所谓二叉树遍历是按某种特定规则,依次对二叉树中的节点进行相应的操作,并且每个节点只操作一次.访问结点所做的操作依赖于具体的应用问题. 遍历是二叉树上最重要的运算之一,也是二叉树进行其它运算的基础. 二 ...

  2. 【数据结构与算法】力扣:二叉树的前、中、后序遍历

    递归法 前序遍历 给你二叉树的根节点 root ,返回它节点值的前序 遍历. 示例 1: 输入:root = [1,null,2,3] 输出:[1,2,3] 示例 2: 输入:root = [] 输出 ...

  3. 二叉树的前、中、后序遍历的代码实现(递归方式)

    测试的二叉树的结构 root lfb1 rtb1rtb2 控制台输出的遍历结果 ======从根节点开始,前序遍历此二叉树======= root lfb1 rtb1 rtb2 ======从根节点开 ...

  4. java中二叉树_Java工程师面试1000题224-递归非递归实现二叉树前、中、后序遍历...

    224.使用递归和非递归实现二叉树的前.中.后序遍历 使用递归来实现二叉树的前.中.后序遍历比较简单,直接给出代码,我们重点讨论非递归的实现. class Node { public int valu ...

  5. 二叉树遍历方法——前、中、后序遍历(图解)

    目录 一.前序遍历 (1)递归版本 (2)非递归版本 二.中序遍历 (1)递归版本 (2)非递归版本 三.后序遍历 (1)递归版本 (2)非递归版本 四.总结 五.测试程序 六.程序输出 二叉树的遍历 ...

  6. 二叉树的前、中、后的非递归遍历

    题目 实现一个链式存储的二叉树,采用非递归的形式,按照前.中.后序的顺序遍历二叉树. 代码 /** * 二叉树的前.中.后序的非递归遍历 **/#include <iostream> us ...

  7. 已知一棵二叉树的中序序列和后序序列,写一个建立该二叉树的二叉链表存储结构的算法...

    已知一棵二叉树的中序序列和后序序列,写一个建立该二叉树的二叉链表存储结构的算法 #define N 10 //二叉树节点的个数 char postorderstr[]={};//后序序列 char i ...

  8. 7-10 先序序列创建二叉树,输出先序序列、中序序列、后序序列并输出叶子结点数 (10 分)

    7-10 先序序列创建二叉树,输出先序序列.中序序列.后序序列并输出叶子结点数 (10 分) 对于给定的二叉树,输出其先序序列.中序序列.后序序列并输出叶子结点数. 输入格式: 二叉树的先序遍历序列. ...

  9. 二叉树的构造(前序+中序)---(后序 + 中序)

    二叉树的构造(前序+中序)-(后序 + 中序) 思路:要对前序+中序(后序+中序)的构建树的动态过程要了解,思路比较简单,在了解了这个过程之后,理解下面代码就容易了. 过程 参考图: 前序 + 中序: ...

  10. 先序序列和中序序列构造二叉树,中序序列和后序序列构造二叉树

    1:首先读者要了解二叉树BinaryTree基本概念,其次区分左子树与左孩子节点,右子树与右孩子节点.(在数据结构中      一个节点可以成为一棵树,对于没有孩子节点的节点称为为叶子节点). 2:在 ...

最新文章

  1. SQLAlchemy技术文档(中文版)(中)
  2. 推荐系统中的召回算法--协同过滤
  3. 学习打卡-2018/08/09
  4. 是否要入坑强化学习,看了这篇文章再说
  5. GDI+中常见的几个问题(6)
  6. 隐藏键盘_三星新专利:带有隐藏键盘的三折叠屏手机
  7. php - MySQL创建新用户并授权
  8. 说说python程序的执行过程_做人,尽量不要说这四种话,一说,祸事就来了
  9. 知乎推荐算法工程师面经
  10. 技术·融合·治理|众享链网试运行总结暨正式运行发布会预告
  11. Google推出一款用户隐私保护工具箱
  12. 和平精英体验服服务器更新维护什么意思,和平精英8月9日体验服官方申请地址 和平精英更新6项内容需要多注意!和平精英8月9日更新时间确定...
  13. STC学习:光照报警器
  14. 341.扁平化嵌套列表迭代器
  15. 硬盘录播服务器,高清录播主机录播服务器HT-7500_航天广电录播系统设备
  16. PDFjs的使用说明书
  17. 商标注册流程和周期是什么
  18. VS2019 测试使用libusb
  19. 20135203齐岳 信息安全系统设计基础第四周学习总结
  20. java dozer_java – Dozer双向映射(String,String)与自定义转换器不可能?

热门文章

  1. 虫儿飞计算机音乐,虫儿飞 MIDI File Download :: MidiShow
  2. XXXX项目可实施性报告
  3. HSDPA、WiMAX和LTE关键技术比较与分析
  4. 响应式中小学早教教育机构类网站源码 HTML5教育培训机构网站织梦模板
  5. 【C语言】职工管理系统详解(文件操作)
  6. 关于NTFS与FAT32的互相转化
  7. 2020年中国家居建材行业发展规模及家居重点企业对比分析:顾家家居vs曲美家居[图]
  8. 基于二分查找的抽签游戏算法的优化
  9. 从零开始搭建个人网页II-前端部分
  10. 大学英语计算机等级考试,全新版大学英语综合教程3课文原文及翻译6-8,全国计算机等级考试一级试题及答案(25套).doc...