二叉树先中后序递归遍历与非递归遍历、层次遍历
文章目录
- 1 先序遍历
- 1.1 先序遍历递归
- 1.2 先序遍历非递归
- 2 中序遍历
- 2.1 中序遍历递归
- 2.2 中序遍历非递归
- 3 后序遍历
- 3.1 后序遍历递归
- 3.2 后序遍历非递归
- 4 层序遍历
1 先序遍历
若二叉树为空,则操作返回,否则先访问根结点,然后前序遍历左子树,再前序遍历右子树
1.1 先序遍历递归
void PreviousOrderTraverse(BTNode T) {if (T == NULL) {return;}/* 对节点的操作 */PreviousOrderTraverse(T->lchild); // 先序遍历左子树PreviousOrderTraverse(T->rchild); // 再先序遍历右子树
}
1.2 先序遍历非递归
递归的实现依赖于栈,那么就将二叉树的递归遍历转换为非递归遍历,也就是利用栈来实现
void PreviousOrderTraverse(BTNode *bt)
{if(bt !=NULL){BTNode *Stack[maxSize]; int top=-1;BTNode *p=NULL; //p为遍历指针Stack[++top]=bt;while(top!=-1){p=Stack[top--]; //根结点出栈并访问visit(p);if(p->rchild!=NULL)//检测左右孩子是否存在Stack[++top]=p->rchild; //先入if(p->rchild!=NULL)Stack[++top]=p->lchild;}}
}
2 中序遍历
若二叉树为空,则操作返回,否则从根节点开始(注意不是先访问根结点),中序遍历根结点的左子树,然后是访问根结点,最后中序遍历右子树
2.1 中序遍历递归
void InOrderTraverse(BTNode T) {if (T == NULL) {return;}InOrderTraverse(T->lchild); // 先中序遍历左子树/* 对结点的操作 */InOrderTraverse(T->rchild); // 再中序遍历右子树
}
2.2 中序遍历非递归
void InOrderTraverse(BTNode *bt)
{BTNode p = T; // p 是遍历指针Stack S = CreateStack(MAXSIZE); // 初始化栈while (p != NULL || !IsEmpty(S)) { // 栈不为空或 p 不为空时遍历if (p != NULL) {Push(S, p); // 一直向左并将沿途节点压入堆栈p= p->leftChild;} else { // p 为空时,栈不为空,弹出节点访问右孩子p= Pop(S); // 弹出堆栈visit();//访问节点p = p->rightChild;}}
}
3 后序遍历
若二叉树为空,则操作返回,否则从左到右,先叶子后结点的方式遍历访问左右子树,最后是访问根结点
3.1 后序遍历递归
void PostOrderTraverse(BTNode T) {if (T == NULL) {return;}PostOrderTraverse(T->lchild); // 先后序遍历左子树PostOrderTraverse(T->rchild); // 再后序遍历右子树/* 对结点的操作 */
}
3.2 后序遍历非递归
- 后序非递归遍历二叉树的顺序是先访问左子树,再访问右子树,最后访问根结点。当用堆栈存储结点时,必须分清返回根结点时是从左子树返回还是从右子树返回的;因此,必须使用辅助指针指向最近访问过的结点。
void PostOrderTraverse(BTNode T) {BTNode p = T; // p 为遍历指针BTNode pTop = NULL; // pTop 为临时指针BTNode pLast = NULL; // pLast 为保存已访问节点指针Stack S = CreateStack(MAXSIZE); // 初始化栈while (p != NULL || !IsEmpty(S)) { // 栈不为空或 p 不为空时遍历 while (p != NULL) {Push(s, p); // 一直向左并将沿途节点压入堆栈 p = p->lchild;}pTop = GetStackTop(s); // 取栈顶元素,不是出栈//当栈顶元素的右孩子为空,或者为已经遍历过的节点if (pTop->rchild == NULL || pTop->rchild == pLast) {StackPop(s); // 出栈,打印,并令遍历过的节点为此时的栈顶元素visit();//访问节点pLast = pTop; // 将 pTop 设为已经遍历过的节点 continue; // 继续循环}p = pTop->rchild; //遍历它的右孩子}
}
- 在先序遍历非递归上进行修改,先进左孩子,再进右孩子得逆后序序列,再借助一个栈将逆后序序列转化为后序序列
void PostorderTraverse(BTNode *bt)
{if(bt!=NULL){/*定义两个栈*/BTNode *Stack1[maxSize]; int top1=-1; //遍历栈 BTNode *Stack2[maxSize]; int top2=-1; //结果序列逆序的栈BTNode *p=NULL;Stack1[++top1]=bt;while(top1!=NULL){p=Stack1[top1--];Stack2[++top2]=p; //每次1出栈,便进2栈 /* 以下与先序遍历区别:左右孩子入栈顺序相反*/if(p->lchild!=NULL)Stack1[++top1]=p->lchild;if(p->rchild!=NULL)Stack1[++top1]=p->rchild; }while(top2!=-1){/*出栈序列即为后序遍历序列*/p=Stack2[top2--];visit(p); //visit是访问p的函数,此处执行打印结点值操作 }}
}
4 层序遍历
若二叉树为空,则操作返回,否则从树的第一层,也就是根结点开始访问,从上而下逐层遍历,在同一层中,按从左到右的顺序对结点逐个访问
- 根结点入队
- 从队列中取出一个元素
- 访问该元素所指的结点
- 若该元素所指结点的左右孩子为非空,则将其左、右孩子的指针顺序入队
void LevelTraverse(BTNode *bt)
{if(bt!=NULL) //根结点不空即树不空 {int front,rear;BTNode *que[maxSize];front=rear=0;BTNode *p; //p是遍历指针 rear=(rear+1)%maxSize;que[rear]=bt; //根结点入队 while(front!=rear) //队列为空则遍历结束 {front=(front+1)%maxSize;p=que[front];visit(p);if(p->lchild!=NULL){rear=(rear+1)%maxSize;que[rear]=p->lchild; //如果左子树不空,则入队 } if(p->rchild!=NULL){rear=(rear+1)%maxSize;que[rear]=p->rchild; //如果右子树不空,则入队 } }}
}
二叉树先中后序递归遍历与非递归遍历、层次遍历相关推荐
- 二叉树前中后序遍历以及节点计算
二叉树前中后序遍历以及节点计算 二叉树 分类 二叉链的数据结构 三叉链的数据结构 四种遍历方法 深度优先遍历:前中后序 广度优先遍历:层序遍历 计算 节点个数 叶子节点个数 树的高度 第k层的节点个数 ...
- 二叉树前中后序遍历的非递归实现以及层次遍历、zig-zag型遍历详解
前言 二叉树的遍历是一个比较常见的问题,递归实现二叉树的前中后序遍历比较简单,但非递归实现二叉树的前中后序遍历相对有难度.这篇博客将详述如何使用非递归的方式实现二叉树的前中后序遍历,在进行理论描述的同 ...
- 二叉树前中后序遍历+刷题【中】【数据结构/初阶/C语言实现】
文章目录 1. 二叉树基础操作 1.1 二叉树遍历 1.1.1 前序遍历 前序遍历(Pre-Order Traversal) 1.1.2 中序遍历 中序遍历(In-Order Traversal) 1 ...
- 线索二叉树(前中后序线索化/遍历/画线索)
线索二叉树 文章目录 线索二叉树 1 线索二叉树的基本概念 2 线索二叉树的构造 2.1 线索二叉树的存储结构 2.2 给线索二叉树画线索 2.2.1 中序 2.2.2 先序 2.2.3 后序 2.3 ...
- 【霍罗维兹数据结构】二叉树前中后序遍历 | 层序遍历 | 复制二叉树 | 判断两个二叉树全等 | 可满足性问题
写在前面 学习二叉树结构,最简单的方式就是遍历.所谓二叉树遍历,就是按照某种特定的规则,一次对二叉树中的节点进行相应的操作,并且每个节点只操作一次. 访问节点所做的操作要看具体的应用问题.遍历是二叉树 ...
- 数据结构-二叉树(包含二叉树的层次建树、前中后序遍历、层次遍历解析及代码)
目录 一.树与二叉树的原理解析 1.树的定义 2.树的结构和特点 3.二叉树的定义 4.树结点的数据结构 二.二叉树的层次建树 1.二叉树层次建树的原理及分析 2.完整代码 三.二叉树的前中后序遍历 ...
- 图解二叉树的先中后序遍历
二叉树前中后序介绍 对于一个二叉树而言,前序(根左右),中序(左根右),后序(左右根) . 可以简单这样理解: 所有的顺序都是以根在根.左.右 三个元素中的位置来决定的.根在前面,就是前序(根左右), ...
- LeetCode——树:层次遍历、前中后序遍历
LeetCode--树:层次遍历.前中后序遍历 目录 层次遍历 二叉树的层平均值 找树左下角的值 前中后序遍历 概述 非递归实现二叉树的前序遍历 非递归实现二叉树的中序遍历 非递归实现二叉树的后序遍历 ...
- 二叉树层序遍历递归与非递归_总结归纳:二叉树遍历【递归 amp;amp; 非递归】...
今天为大家总结了二叉树前中后序遍历的递归与迭代解法: 1. 前序遍历 递归 List list=new ArrayList<>();public ListpreOrder(TreeNode ...
最新文章
- golang 代码实现 修改配置文件
- 如何把控产品 — 产品管理全流程解析
- nyoj 寻找最大数
- 动态数据源切换的底层原理-DynamicDataSourceEntry
- 导出EXCEL中的文件到资源管理器
- 如何使用CSS实现居中
- C#中使用NPIO实现导入导出Excel简单操作
- 微软为“离线”做好准备:推出同步框架
- 期末大作业图书管理系统(c++)源代码
- 2021-03-08-java-pdf导出-lowagie
- python查询电脑序列号 CPU、主板、硬盘、MAC、BIOS
- win10 20h2 计算机属性,Win10 20H2
- 超好用的搜索引擎推荐
- c语言公历转农历程序,用c如何编写 农历转换成公历
- hotmail 获取邮箱授权码
- 用c语言编写计算器计划报告书,用c语言编写计算器计划报告书.docx
- 学生版计算机隐藏游戏,玩了近15年的QQ,才发现这3个隐藏功能,学生党看完炸锅了!...
- 字符在计算机中的存储
- strstr的用法(转)
- 实现radio取消选中的功能
热门文章
- Linux 僵尸进程可以被杀死吗?
- 计算机网络在实践中的应用,计算机网络技术及在实践中的应用
- java .jvp文件_GitHub - eddylapis/jvppeteer: Headless Chrome For Java (Java 爬虫)
- python是面向对象还是过程_python编程:面向对象与过程是什么?
- Flink-Sink_将结果输出到Kafka_Redis_ES_Mysql中
- OpenCV_04 几何变换:图像缩放+图像平移+图像旋转+仿射变换+透射变换+图像金字塔
- LeetCode 1658. 将 x 减到 0 的最小操作数(哈希)
- 【Kaggle微课程】Natural Language Processing - 2.Text Classification
- LeetCode 1522. Diameter of N-Ary Tree(递归)
- LeetCode 453. 最小移动次数使数组元素相等(数学)