二叉树的非递归及层次遍历

1.前序遍历

遍历顺序:根节点→左孩子→右孩子

具体算法思想:将二叉树的根结点赋值给遍历的指针,由该指针进行遍历;若当前节点非空,则访问该节点并将该节点压栈(将该节点的地址压栈),继而遍历其左子树;循环执行,直到当前节点为空时,取栈顶元素并访问其右子树,再重复如上操作,直至遍历节点的指针为空且栈也为空;

具体遍历过程如图:

算法代码实现如下:

void preorder(BiTree T){//二叉树的非递归前序遍历 stack<BiTree> s;while(T||!s.empty()){//当前结点或栈不为空时执行该循环 if(T!=NULL){//当前结点不为空时 cout<<T->data;//访问当前结点信息 s.push(T);//将该节点的地址压栈 T=T->lchild;//遍历左孩子 }else{//当前结点为空时 T=s.top();//取栈顶的元素 s.pop();//弹栈 T=T->rchild;//遍历右孩子 }}
}

2.中序遍历

遍历顺序:左孩子→根节点→右孩子

具体算法思想:将二叉树的根结点赋值给遍历的指针,由该指针进行遍历;若当前节点非空,则将该节点压栈并访问其左子树,循环执行,直至当前节点为空时,取栈顶元素访问并弹栈,然后访问其右子树,再重复如上操作,直至遍历节点的指针为空在且栈也为空。(中序遍历和前序遍历的不同在于:前序遍历是入栈的同时访问结点,而中序遍历是出栈的同时访问结点);

具体遍历过程如图:

算法代码实现如下:

void inorder(BiTree T){//二叉树的非递归中序遍历 stack<BiTree> s;while(T||!s.empty()){//当前结点或栈不为空时执行该循环 if(T!=NULL){//当前结点不为空时s.push(T);//将该节点的地址压栈T=T->lchild;//遍历左孩子}else{T=s.top();//取栈顶的元素s.pop();//弹栈cout<<T->data;//访问当前结点信息T=T->rchild;//遍历右孩子         }}
}

3.后序遍历

遍历顺序:左孩子→右孩子→根节点

具体算法思想:将二叉树的根结点赋值给遍历的指针,由该指针进行遍历;若当前节点非空,则将该节点压栈并访问其左子树,循环执行,直至当前节点为空时,取栈顶元素,判断其右子树是否为空且是否已遍历,如果非空且为遍历则访问其右子树,再将其压栈遍历其左子树;如果右子树为空或已遍历则访问该结点并弹栈,同时设置标记指针记录遍历过的点(用于判断右子树是否已遍历),再将遍历指针置空(下次遍历直接取栈顶元素),直至遍历节点的指针为空且栈也为空。

算法代码实现如下:

void postorder(BiTree T){//二叉树的非递归后序遍历 BiTree r=NULL;stack<BiTree> s;while(T||!s.empty()){if(T!=NULL){//当结点不为空时,该结点压栈并遍历其左子树 s.push(T);T=T->lchild;}else{//当左子树结点为空时,取栈顶元素进行右子树的遍历, T=s.top();if(T->rchild!=NULL&&T->rchild!=r){//右子树不为空且右子树没有被遍历过 T=T->rchild;s.push(T);//将该结点压栈,遍历其左子树 T=T->lchild;}else{//右子树为空或已遍历则取栈顶元素访问该结点的信息 s.pop();cout<<T->data;r=T;//标记遍历过的点,用于判断右子树是否已遍历 T=NULL;//遍历结点的指针置空,下次遍历直接取栈中的值 }}}
}

4.层次遍历

具体算法思想:将根节点入队,访问队头元素,并将其左右孩子入队,循环直至队列为空结束。

算法代码实现如下:

void leveorder(BiTree T){//层次遍历 deque<BiTree> d;if(T)//根结点不为空时入队 d.push_back(T); while(!d.empty()){//当队不为空时循环 T=d.front();//取队头元素并访问该点信息 cout<<T->data;if(T->lchild)//将该结点的左孩子和右孩子纳入队中 d.push_back(T->lchild);if(T->rchild)d.push_back(T->rchild);d.pop_front();//队头元素出队}
}

5.具体实现

#include <bits/stdc++.h>
#define INIT ios::sync_with_stdio(false)
using namespace std;
typedef struct BiTNode{int data;struct BiTNode *lchild,*rchild;
}BiNode,*BiTree;
void creat(BiTree &T){int n;cin>>n;if(n==0)//输入0时表示结点为空 T=NULL;else{T=new BiNode;T->data=n;creat(T->lchild);//创建左子树 creat(T->rchild);//创建右子树 }
}
void preorder(BiTree T){//二叉树的非递归前序遍历 stack<BiTree> s;while(T||!s.empty()){//当前结点或栈不为空时执行该循环 if(T!=NULL){//当前结点不为空时 cout<<T->data;//访问当前结点信息 s.push(T);//将该节点的地址压栈 T=T->lchild;//遍历左孩子 }else{//当前结点为空时 T=s.top();//取栈顶的元素 s.pop();//弹栈 T=T->rchild;//遍历右孩子 }}
}
void inorder(BiTree T){//二叉树的非递归中序遍历 stack<BiTree> s;while(T||!s.empty()){//当前结点或栈不为空时执行该循环 if(T!=NULL){//当前结点不为空时s.push(T);//将该节点的地址压栈T=T->lchild;//遍历左孩子}else{T=s.top();//取栈顶的元素s.pop();//弹栈cout<<T->data;//访问当前结点信息T=T->rchild;//遍历右孩子         }}
}
void postorder(BiTree T){//二叉树的非递归后序遍历 BiTree r=NULL;stack<BiTree> s;while(T||!s.empty()){if(T!=NULL){//当结点不为空时,该结点压栈并遍历其左子树 s.push(T);T=T->lchild;}else{//当左子树结点为空时,取栈顶元素进行右子树的遍历, T=s.top();if(T->rchild!=NULL&&T->rchild!=r){//右子树部位空且右子树没有被遍历过 T=T->rchild;s.push(T);//将该结点压栈,遍历其左子树 T=T->lchild;}else{//右子树为空或已遍历则取栈顶元素访问该结点的信息 s.pop();cout<<T->data;r=T;//标记遍历过的点,用于判断右子树是否已遍历 T=NULL;//遍历结点的指针置空,下次遍历直接取栈中的值 }}}
}
void leveorder(BiTree T){//层次遍历 deque<BiTree> d;if(T)//根结点不为空时入队 d.push_back(T); while(!d.empty()){//当队不为空时循环 T=d.front();//取队头元素并访问该点信息 cout<<T->data;if(T->lchild)//将该结点的左孩子和右孩子纳入队中 d.push_back(T->lchild);if(T->rchild)d.push_back(T->rchild);d.pop_front();//队头元素出队}
}
int main() {INIT;BiTree T;creat(T);preorder(T);//先序 cout<<endl;inorder(T);//中序 cout<<endl;postorder(T);//后序 cout<<endl;leveorder(T);//层次 cout<<endl;return 0;
}

二叉树的非递归遍历算法相关推荐

  1. 树:二叉树的非递归遍历算法

    二叉树的递归遍历 二叉树的递归遍历算法,写法很简单,比如说前序遍历树,如下: //前序遍历 void PreOrderTraverse(BiTree tree) {if (NULL != tree){ ...

  2. 二叉树的非递归遍历算法C语言实现(详细注释版)

    二叉树的非递归算法遍历分为:先序遍历,中序遍历,后序遍历. 此文章我会根据先.中.后的顺序为大家用C语言实现全部代码. 顾名思义先序遍历是先遍历根节点,随后是左孩子,右孩子 . 中序遍历与后序遍历可以 ...

  3. 数据结构——二叉树的递归遍历算法与非递归遍历算法+层次遍历算法

    (文章篇幅有点长,二叉树的递归遍历算法不作详细分析,但是二叉树的非递归遍历算法和层次遍历算法都有非常详细的分析过程,记得往下翻哦!) 二叉树的递归遍历算法实现 我们首先用递归的方法先序遍历创建这样一棵 ...

  4. 实现二叉树的三种非递归遍历算法

    [问题描述] 编写程序,实现二叉树的三种非递归遍历算法:先序非递归,中序非递归,后序非递归. [输入形式] 输入建树序列. [输出形式] 输出三种遍历序列. [样例输入] A B C # # # # ...

  5. 刷题:二叉树的非递归遍历方式

    二叉树的非递归的遍历方式 上篇博客记录了二叉树的递归遍历方式以及根据二叉树的遍历结果还原二叉树的内容. 本篇博客记录二叉树的非递归的遍历方式. 二叉树的非递归遍历需要借助栈来实现,而且三种遍历的方式的 ...

  6. 二叉树的非递归遍历(c/c++)

    由于递归算法相对于非递归算法来说效率通常都会更低,递归算法会有更多的资源需要压栈和出栈操作(不仅仅是参数,还有函数地址等)由于编译器对附加的一些栈保护机制会导致递归执行的更加低效,使用循环代替递归算法 ...

  7. 二叉树的非递归遍历(统一的模板)

    二叉树的非递归遍历 前言 树的存储结构 先序遍历 先序的递归遍历 先序的非递归遍历 中序遍历 中序的递归遍历 中序遍历的非递归算法 后序遍历 后序的递归遍历 后序的非递归遍历 层次遍历 层次遍历获得每 ...

  8. 数据结构-二叉树的非递归遍历

    前面的章节我们实现了二叉树最基本的遍历方式:递归遍历,代码是如此的简洁:辣么我们为什么还要去学习二叉树的非递归遍历方式呢?众所周知,递归优点是将可以将复杂的问题简单化即大问题拆分成一个个小问题,那么它 ...

  9. c语言以顺序结构存储的二叉树的非递归遍历,C语言二叉树的非递归遍历实例分析...

    本文以实例形式讲述了C语言实现二叉树的非递归遍历方法.是数据结构与算法设计中常用的技巧.分享给大家供大家参考.具体方法如下: 先序遍历: void preOrder(Node *p) //非递归 { ...

  10. 树的递归与非递归遍历算法

    树的递归与非递归遍历算法 树的递归与非递归遍历算法 树的遍历 实例 树遍历的口诀 树的递归遍历代码 树的先序遍历 树的中序遍历 树的后序遍历 递归遍历思想 树的非递归遍历 树的先序非递归遍历 先序遍历 ...

最新文章

  1. 腾讯会议又一黑科技,屏蔽超过 200 种会议噪声是如何做到的?
  2. android编译的tool版本有多少,macOS Mojave(10.14.2)系统上编译LunarG/VulkanTools工程的Android版本...
  3. dns-prefetch,新打开页面预抓取
  4. 关于Matconvnet中模型发布与共享的思考
  5. 使用Chrome快速实现数据的抓取(四)——优点
  6. 时序数据处理工具-时间序列数据特征提取TsFresh
  7. ionic 添加地图定位功能
  8. NSA泄露的恶意软件DoublePulsar感染了数万台Windows电脑
  9. linux系统调用sysconf(获取系统信息)
  10. vs2008 调试js
  11. 嵌入式操作系统内核原理和开发(实时系统中的定时器)
  12. zen3架构_AMD Zen3架构升级,AMD最新产品一览
  13. git整理——廖雪峰教程笔记
  14. JAVA实现经典游戏俄罗斯方块
  15. 【Unity3D】个人开发台球小游戏
  16. 7-6 打妖怪 (10 分)
  17. 清华大学计算机崔勇,崔勇 简历 - 名人简历
  18. 【基因】原核生物基因调控机制,操纵子学说整理——2015年7月17日
  19. iOS设计模式之MVC
  20. 硫酸软骨素-聚乙二醇-卵清蛋白,Chondroitin sulfate-PEG-OVA/Ovalbumin

热门文章

  1. 【电子书制作软件哪个好】云展网教程 | 搜索功能:搜索杂志内文字可高亮
  2. 英文参考文献的正确引用格式详解
  3. HTML5+CSS3 为图书简介页面添加图像及视频
  4. 处理数码照片的计算机需要配置,用Photoshop处理数码照片_计算机软件及应用_IT计算机_专业资料.doc...
  5. 用计算机看手机照片大小,手机怎么知道照片多少k
  6. 使用 .NET HttpClient 下载 PDF 文件的DEMO
  7. 自定义网站地址栏图标
  8. CATIA_CAA_RADER26+VS2012安装教程
  9. 双向三相交错并联DC-DC变换器
  10. 酷派android4.4.4到5.0,酷派大神F1电信版升级安卓5.0刷机教程[多图]