二叉树(Binary Tree):先序遍历、中序遍历、后序遍历和层次遍历

  • 树 Tree
  • 二叉树 Binary Tree
    • 先序遍历 Preorder Traversal
    • 中序遍历 Inoreder Traversal
    • 后序遍历 Postorder Traversal
    • 层次遍历 Level Traversal

树 Tree

  • Root:树顶部的顶点,记为r
  • 路径 Path:树中的路径是连接一个顶点到另一个顶点的顶点和边的序列,顶点y到顶点v的路径记为y∗→Tv_y \ \underrightarrow{*}_T\ {_v}y​ ∗​T​ v​ 。
  • 深度 Depth:一个顶点v的深是路径r∗→Tv_r \ \underrightarrow{*}_T\ {_v}r​ ∗​T​ v​上边的数目。
  • 层次 Level:从根结点开始,根结点的层次为1,根的直接后继层次为2,以此类推。
  • 节点的度:节点子树个数。
  • 父亲 Parent:如果在树上存在一个边(p,v)(p,v)(p,v),则顶点p是顶点v的父亲。
  • 孩子 Child:如果在树上存在一个边(p,v)(p,v)(p,v),则顶点v是顶点p的父亲。
  • 兄弟 Sibling:有相同父亲的顶点。
  • 祖先 Ancestor:如果a在路径a∗→Tv_a \ \underrightarrow{*}_T\ {_v}a​ ∗​T​ v​ (包括v)上,则顶点a是v的祖先。
  • 后代 Descendant:顶点a是顶点v的祖先,则va的后代,包括顶点自己。
  • 真祖先 Proper Ancestor:和祖先的一样,但不包括自己,真祖先a到顶点v的路径记为:a+→Tv_a \ \underrightarrow{+}_T\ {_v}a​ +​T​ v​ 。
  • 真后代 Proper descendant:和后代一样,但不包括自己。
  • 子树 Subtree:顶点v是树中的一个顶点,有v和其后代组成的的树为T的子树,顶点v是该子树的根。
  • 单体 Singlenton:只有一个顶点的树。
  • 森林 Forest:森林就是一系列的树,这些树不互相连接。
  • 叶结点 Leaf :度为0的结点称为叶结点,也可以叫做终端结点;

二叉树 Binary Tree

二叉树:所有节点的度不超过2的树。
满二叉树:一种二叉树,叶子节点都在最下面一层,并且除了叶子节点外每个节点度都为2。
完全二叉树:一种二叉树,叶子节点只能位于最下面一层或次最下面一层,并且最下面一层都位于最左边的若干子树。

二叉树最常使用的存储是采用链式存储:

typedef int ElemType;
class TreeNode{private:ElemType val;TreeNode* lchild;TreeNode* rchild;
public:TreeNode(ElemType x) : val(x), child(nullptr), rchild(nullptr) {}
}

先序遍历 Preorder Traversal

先序遍历:先访问根节点,然后访问左子树,最后访问右子树。ABDECFG。

递归版本

void PreOrder(TreeNode* root){if(root == nullptr) return;visit(root);PreOrder(root->lchild);PreOrder(root->rchild);
}

非递归版本

借助栈来完成。

  1. 沿着左孩子访问,并依次入栈,直到左孩子为空。
  2. 栈顶元素出栈,若其右孩子为空,继续步骤2,否则对右孩子执行步骤1。
void PreOrder1(TreeNode* root){if(root == nullptr) return;Stack<TreeNode*> s;TreeNode* p = root;while(p != nullptr || !s.empty()) {if (p != nullptr) {visit(p);s.push(p);p = p->lchild;} else {p = s.pop();p = p->rchild;}}
}

中序遍历 Inoreder Traversal

中序遍历:先访问左子树,然后访问根节点,最后访问右子树。DBEAFCG。

递归版本

void InOrder(TreeNode* root){if(root == nullptr) return;PreOrder(root->lchild);visit(root);PreOrder(root->rchild);
}

非递归版本

算法和先序遍历类似,只是访问根节点时机改变了。

  1. 沿着左孩子,依次入栈,直到左孩子为空。
  2. 栈顶元素出栈并访问,若其右孩子为空,继续步骤2,否则对右孩子执行步骤1。
void InOrder1(TreeNode* root){if(root == nullptr) return;Stack<TreeNode*> s;TreeNode* p = root;while(p != nullptr || !s.empty()) {if (p != nullptr) {s.push(p);p = p->lchild;} else {p = s.pop();visit(p);p = p->rchild;}}
}

后序遍历 Postorder Traversal

后序遍历:先访问左子树,然后访问右子树,最后访问根节点。DEBFGCA。

递归版本

void PostOrder(TreeNode* root){if(root == nullptr) return;PreOrder(root->lchild);PreOrder(root->rchild);visit(root);
}

非递归版本

也借助栈:

  1. 沿着左孩子,将其依次入栈,直到左孩子为空。
  2. 读取栈顶元素(但不出栈),若其有孩子为空且未被访问过,对右孩子执行步骤1,否则,栈定元素出栈并访问。
void PostOrder1(TreeNode* root){if(root == nullptr) return;TreeNode* p = root;TreeNode* visited = nullptr;Stack<TreeNode*> s;while (p != nullptr || !s.empty()) {if (p != nullptr) {s.push(p);p = p->lchild;} else {p = s.top();if (p->rchild != nullptr && p->rchild != visited) {s.push(p->rchild);p = p->rchild->lchild;} else {p = s.pop();visit(p);visited = p;p = nullptr;  }}}
}

层次遍历 Level Traversal

层次遍历:按照层,上一层遍历完,再遍历下一层,每一层先访问左边节点,再访问右边节点。ABCDEFG。

需要借助队列,先将根节点入队,然后出队并访问。若它有左孩子则左孩子根节点入队,若它有右孩子则右孩子根节点入队。
接着出队并访问,继续上述步骤,直到队列为空。

void LevelOrder1(TreeNode* root){if(root == nullptr) return;queue<TreeNode*> q;q.push(root);while (!q.empty()) {TreeNode* p = q.front();q.pop();visite(p);if (p->lchild != nullptr) {q.push(p->lchild);}if (p->rchild != nullptr) {q.push(p->rchild);}}
}

参考:

  • [1] https://blog.csdn.net/Real_Fool_/article/details/113930623?spm=1001.2014.3001.5506
  • [2] 算法导论

二叉树(Binary Tree):先序遍历、中序遍历、后序遍历和层次遍历相关推荐

  1. 由任意二叉树的前序遍历序列和中序遍历序列求二叉树的思想方法_算法与数据结构基础 - 二叉树(Binary Tree)...

    二叉树基础 满足这样性质的树称为二叉树:空树或节点最多有两个子树,称为左子树.右子树, 左右子树节点同样最多有两个子树. 二叉树是递归定义的,因而常用递归/DFS的思想处理二叉树相关问题,例如Leet ...

  2. 二叉树前序中序后序_leetcode889_go_根据前序和后序遍历构造二叉树

    leetcode889_根据前序和后序遍历构造二叉树 01 - 题目 返回与给定的前序和后序遍历匹配的任何二叉树. pre 和 post 遍历中的值是不同的正整数. 示例:输入:pre = [1,2, ...

  3. 已知二叉树先序和中序遍历结果,求后序遍历结果

    以下面的例题为例进行讲解:已知一棵二叉树的先序遍历序列和中序遍历序列分别是ABDCEF.BDAECF,求二叉树及后序遍历序列. 分析:先序遍历序列的第一个字符为根结点.对于中序遍历,根结点在中序遍历序 ...

  4. 二叉树前序遍历python输出_[宜配屋]听图阁 - Python实现输入二叉树的先序和中序遍历,再输出后序遍历操作示例...

    本文实例讲述了Python实现输入二叉树的先序和中序遍历,再输出后序遍历操作.分享给大家供大家参考,具体如下: 实现一个功能: 输入:一颗二叉树的先序和中序遍历 输出:后续遍历 思想: 先序遍历中,第 ...

  5. 为什么普通树没有中序遍历和森林没有后序遍历

    本文为个人理解,若有错误欢迎指正! 这里说的树当然是指普通的树,而不是树中比较特别的二叉树. 1.为什么普通树没有中序遍历 中序遍历是对于二叉树而言: 中序遍历左子树,访问根结点,中序遍历右结点. 在 ...

  6. 【数据结构】二叉树 (Binary Tree)

    目录 一. 什么是树? 二. 二叉树 特殊二叉树 二叉树的性质 二叉树的存储 二叉树的遍历 二叉树的基本操作 一.什么是树? 之前咱们学习了一些简单的数据结构,如顺序表,链表,这些都是线性结构,线性结 ...

  7. 『数据结构与算法』解读树(Tree)和二叉树(Binary Tree)!

    『数据结构与算法』解读树(Tree)和二叉树(Binary Tree)! 文章目录 一. 树 1.1. 树的定义 1.2. 树的基本术语 1.3. 树的性质 二. 二叉树 2.1. 二叉树的定义 2. ...

  8. 二叉树 Binary Tree

    我怀着激动的心 走上了这颗树 今天是2021年11月12日 今天开始上树!!!!!! 生活中的树形结构: 树:  根节点: 一棵树有且只有一个根节点就是最上面的节点 兄弟节点: 每一行的节点  它们具 ...

  9. 【数据结构】二叉树(Binary Tree)

    目录 1 树的概念 1.1 树的定义 1.2 相关概念 2 二叉树的概念 2.1 二叉树的定义 2.2 二叉树的性质 2.3 特殊二叉树 2.3.1 满二叉树 2.3.2 完全二叉树 3 二叉树的储存 ...

  10. [LeetCode] Construct Binary Tree from Preorder and Inorder Traversal 由先序和中序遍历建立二叉树...

    Given preorder and inorder traversal of a tree, construct the binary tree. Note: You may assume that ...

最新文章

  1. 解读 | 2019 年 10 篇计算机视觉精选论文
  2. 4.3 IDEA 常用快捷键
  3. Python安装PyOpenGL
  4. Hibernate的关联映射--一对多、
  5. Ubuntu版本更新一路走来:朕就是这样的汉子
  6. Zookeeper系列(一)
  7. Java 学习总结(189)—— Java 8 功能接口使用总结
  8. Buffer对象与JSON对象相互转换
  9. (大数据工程师学习路径)第三步 Git Community Book----高级技能
  10. Android - 找到当前类的Context
  11. python实现不使用额外的空间判断输入数字是否是回文数
  12. JavaScript 教程
  13. 数据仓库是什么?和数据库有何区别?
  14. 网络新文化现象:newbilitynbsp;(不代表…
  15. 网页加载java慢_为什么开网页很慢 网页打开速度慢的原因【解决方法】
  16. CentOS 6.3下Samba服务器的安装与配置
  17. 【Pandas】解决在pandas中的两个正数相乘结果为负值
  18. 7-1 汽车加油问题 (15分)
  19. #我的第二十一堂云计算课# #开源数据库MySQL DBA运维实战 第2章 SQL1#
  20. 器件封装——SMA/SMB/SMC

热门文章

  1. 盖茨基金会宣布再追加捐赠1.5亿美元,支持全球新冠肺炎响应行动
  2. MyOS(三):软盘读写
  3. doom emacs如何安装新插件和自定义快捷键
  4. HarmonyOS实战——TickTimer定时器组件基本使用
  5. PHP实现页面静态化、纯静态化及伪静态化
  6. 祝福语html特效,2015年微信祝福语特效
  7. 【Linux】解压缩命令
  8. Java从入门到精通十七(Stream 流)
  9. win10系统网络图标变成小地球的解决方法
  10. excel表如何汇总统计平均值