前两天做数据结构实验,要求用非递归算法遍历二叉树。只知道用栈来储存数据,具体算法还不太清楚。经过两天的搜索,看到网上很多种解法,很多解法都是用C++来写的算法,一直找不到用C语言写的算法,所以就总结了一下,用C写出了一个遍历二叉树的三种非递归算法。

前序遍历

前序遍历按照“根结点-左孩子-右孩子”的顺序进行访问。
具体算法:先遍历左孩子,并输出。当左孩子遍历完后,取栈顶,找右孩子。此时循环还没有结束,再遍历它的左孩子,右孩子直至孩子全部遍历结束。

void preorder(bitree *t)//前序遍历的非递归算法
{bitree *temp = t;//定义一个树节点,用它来遍历while(temp != NULL || s.top != 0){while(temp != NULL)//先遍历左孩子,并输出。{printf("%4d",temp->data);push(temp);temp = temp->lchild;}if(s.top != 0)//当左孩子遍历完后,取栈顶,找右孩子。此时循环还没有结束,再遍历它的左孩子,直至孩子全部遍历结束。{temp = pop();temp = temp->rchild;}}printf("\n");
}

中序遍历

中序遍历按照“左孩子-根节点-右孩子”的顺序进行访问。
具体算法:先把左孩子入栈,不着急先输出,先把所有左孩子入栈。左孩子入栈结束,取栈顶,输出栈顶元素,遍历右孩子,右孩子入栈。

void inorder(bitree *t)//中序遍历的非递归算法
{bitree *temp = t;while(temp != NULL||s.top != 0){while(temp != NULL)//先把左孩子入栈,所有左孩子入栈结束{push(temp);temp = temp->lchild;}if(s.top != 0)//左孩子入栈结束,取栈顶,输出栈顶元素,遍历右孩子{temp = pop();printf("%4d",temp->data);temp = temp->rchild;}}printf("\n");
}

后序遍历

后序遍历按照“左孩子-右孩子-根节点”的顺序进行访问。
具体算法:对于任一结点P,将其入栈,然后沿其左子树一直往下搜索,直到搜索到没有左孩子的结点,此时该结点出现在栈顶,但是此时不能将其出栈并访问,因此其右孩子还为被访问。所以接下来按照相同的规则对其右子树进行相同的处理,当访问完其右孩子时,该结点又出现在栈顶,此时可以将其出栈并访问。这样就保证了正确的访问顺序。可以看出,在这个过程中,每个结点都两次出现在栈顶,只有在第二次出现在栈顶时,才能访问它。因此需要多设置一个变量标识该结点是否是第一次出现在栈顶。

void laorder(bitree *root)//后序遍历的非递归算法
{bitree *temp = root;while(temp!=NULL||s.top!=0){while(temp!= NULL){temp->cishu=1;       // 当前节点首次被访问push(temp);temp=temp->lchild;}if(s.top!=0){temp=pop( );if(temp->cishu == 1)   // 第一次出现在栈顶{temp->cishu++;push(temp);temp=temp->rchild;}elseif(temp->cishu==2)//第二次输出并制空,防止陷入死循环{printf("%4d",temp->data);temp=NULL;}}}printf("\n");
}

一个完整的程序

#include <stdio.h>
#include <stdlib.h>
#define NULL 0
#define M 100
typedef struct node
{  int data;int cishu;struct node *lchild;  struct node *rchild;  //树节点中cishu是为了计数用。在后序遍历中,子树的根节点在第一次遍历的时候不会输出,只有在第二次遍历的时候才输出。
}bitree;typedef struct stack
{bitree *elements[M];int top;
}seqstack;//定义一个储存树类型地址的栈,方便遍历的时候追踪到树的地址。bitree *root;//定义一个树根
seqstack s;//定义栈void setnull()//初始化栈
{s.top =0;
}void push(bitree *temp)//入栈操作
{s.elements[s.top++] = temp;
}bitree *pop()//取栈顶并出栈顶
{return s.elements[--s.top];
}int empty()//判断空栈
{return s.top == 0;
}bitree *creat()   /*建立二叉树的递归算法*/
{ bitree *t;int x;scanf("%d",&x);if(x==0) t=NULL; /*以x=0表示输入结束*/else{t=(bitree*)malloc(sizeof(bitree));//动态生成结点t,分别给结点t的数据域、左右孩子域  t->data=x;                  //赋值,给左右孩子域赋值时用到了递归的思想。t->lchild=creat();t->rchild=creat();}return t;
}void preorder(bitree *t)//前序遍历的非递归算法
{bitree *temp = t;//定义一个树节点,用它来遍历while(temp != NULL || s.top != 0){while(temp != NULL)//先遍历左孩子,并输出。{printf("%4d",temp->data);push(temp);temp = temp->lchild;}if(s.top != 0)//当左孩子遍历完后,取栈顶,找右孩子。此时循环还没有结束,再遍历它的左孩子,直至孩子全部遍历结束。{temp = pop();temp = temp->rchild;}}printf("\n");
}void inorder(bitree *t)//中序遍历的非递归算法
{bitree *temp = t;while(temp != NULL||s.top != 0){while(temp != NULL)//先把左孩子入栈,所有左孩子入栈结束{push(temp);temp = temp->lchild;}if(s.top != 0)//左孩子入栈结束,取栈顶,输出栈顶元素,遍历右孩子{temp = pop();printf("%4d",temp->data);temp = temp->rchild;}}printf("\n");
}void laorder(bitree *root)//后序遍历的非递归算法
{bitree *temp = root;while(temp!=NULL||s.top!=0){while(temp!= NULL){temp->cishu=1;       // 当前节点首次被访问push(temp);temp=temp->lchild;}if(s.top!=0){temp=pop( );if(temp->cishu == 1)   // 第一次出现在栈顶{temp->cishu++;push(temp);temp=temp->rchild;}elseif(temp->cishu==2)//第二次输出并制空,防止陷入死循环{printf("%4d",temp->data);temp=NULL;}}}printf("\n");
}int main()
{bitree *root;//创建根setnull();//制空栈root=creat();//创建二叉树:尝试输入:1 2 3 0 0 4 0 0 5 6 0 0 7 0 0printf("前序遍历:\n");preorder(root);printf("中序遍历:\n");inorder(root);printf("后序遍历:\n");laorder(root);return 0;
}

程序验证

建立一个如下图所示的二叉树(图画的不太好看)

结果如下图:

二叉树的非递归遍历(前序中序后序非递归C语言)相关推荐

  1. 二叉树的操作(前,中,后序遍历也叫深度优先遍历,非空结点的个数)递归实现

    定义一个二叉树的结点 二叉树的前序遍历, 先访问根结点,再访问左,再访问右. 每次访问都要先看根结点是否为空,然后打印根结点,把此时根结点的左结点作为下一次递归的根结点,当把左结点遍历完后,再遍历右结 ...

  2. 非递归先、中、后序遍历二叉树(C语言)

    文章目录 前言 一.二叉树非递归遍历算法 1.先序遍历 2.中序遍历 3.后序遍历 二.完整程序 三.运行结果实例 前言 本程序采用C语言编写,栈和二叉树的基本操作函数基于严蔚敏老师的<数据结构 ...

  3. 【二叉树Java】二叉树遍历前序中序后序遍历的非递归写法

    本文主要介绍二叉树前序中序后序遍历的非递归写法 在探讨如何写出二叉树的前序中序后序遍历代码之前,我们先来明确一个问题,前序中序后序遍历根据什么区分? 二叉树的前序中序后序遍历,是相较根节点说的.最先遍 ...

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

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

  5. 二叉树的前序中序后序 递归与非递归解法

    转自https://www.cnblogs.com/songwenjie/p/8955856.html 二叉树遍历原理 二叉树的遍历是指从根结点出发,按照某种次序依次访问二叉树中所有结点,使得每个结点 ...

  6. 二叉树的深度(前序 中序 后序 递归非递归搜素)、广度、搜索 C++

    a b c 使用 1 2 3 表示 /* 描述:二叉树的深度(前序 中序 后序 递归非递归搜素).广度.搜索 作者:jz 日期:20140819 */ #include<stdio.h> ...

  7. C++实现二叉树 前、中、后序遍历(递归与非递归)非递归实现过程最简洁版本

    本文并非我所写,是复制的该链接中的内容: 最近学习二叉树,想编程实现递归和非递归的实现方式: 递归的方式就不说了,因为大家的递归程序都一样:但是对于非递归的实现方式, 根据这几天的查阅资料已看到差不多 ...

  8. 二叉树遍历(递归实现前序/中序/后序遍历)

    1. 准备工作 我们先定义一棵普通的二叉树,如下图 2. 前序遍历 通过递归进行遍历: 如果二叉树为空,则操作返回: 如果非空,否则从根结点开始,然后遍历左子树,再遍历右子树. 前序遍历的结果是:AB ...

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

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

  10. 二叉树的前序中序后序三种遍历方式及递归算法介绍

    二叉树三种遍历方式 二叉树的遍历是整个二叉树的核心,二叉树的几本操作都要依赖于遍历,对于二叉树的遍历,递归是最简单也最容易理解的,本文详细介绍了二叉树的三种遍历方法,并用递归来实现: 完整的可调试代码 ...

最新文章

  1. linux ubuntu systemd-udevd进程 cpu占用过高 解决方法
  2. unilever news
  3. CVPR 2022 57 篇论文分方向整理 + 打包下载|涵盖目标检测、语义分割、人群计数、异常检测等方向
  4. 使用 ABAP 手动解析包含二进制文件的 multipart/form-data 数据时遇到的问题
  5. python的if和else、for、while语法_python-变量、if else语句 、for循环、while循环(4月26号)...
  6. 俄国数学家称:“平行线可以相交”,却遭到质疑,死后12年被证实
  7. 转载:PyBus(排忧巴士)的C#源代码(windows mobile手机软件 查询公交的)
  8. AutoIt Windows的自动化脚本
  9. android+祖玛游戏源码,Flash祖玛游戏源代码
  10. 学计算机办公软件多久能学好,学好办公软件的方法 如何快速学好办公软件
  11. 小米 红米【AC2100】一键刷BREED【30秒刷完】小白脑残专用 无需工具TELNET + 检查坏块
  12. [教程]安装系统解码器 - 指导教程
  13. AI把英语系新生吓退学?别急,我们从来都是那只懒蚂蚁
  14. js-url转换blob以及blob与base64的相互转换
  15. mysql存储过程基础写法
  16. 【nn.LSTM详解】
  17. 企业微信版本更新(4.0.0.6003)
  18. 山东自然人电子税务局(扣缴端)_标准!自然人电子税务局扣缴客户端操作指引在这...
  19. 台式APE播放机 硬盘APE播放器 APE Player Ver0.1完成
  20. juce开发vst混响插注意点

热门文章

  1. BUUCTF[羊城杯 2020]easyre
  2. 程序员没对象,是不想找还是真的找不到?
  3. VUE+前端数据存储indexDB
  4. Fisher Discriminant
  5. 流行和声(10)Augmented7和弦
  6. ibm社区文章,有争议 (同步异步,阻塞非阻塞)
  7. 微信小程序中的页面跳转(通过点击按钮、调用方法的形式)
  8. 判断回文字符串(函数实现)
  9. 四川建院计算机专业升本学校,四川哪些专科学校可以升本
  10. EtherCAT igh主站控制埃斯顿伺服(csp模式)