二叉树的非递归算法因为涉及到栈和队列,所以写的时候总是受到伪代码的干扰,要完整的补全栈和队列的结构有些麻烦,这里借鉴了一些大佬的思想,发现可以直接在树中模拟栈和队列的存在,这给非递归的完整代码带来了很大的便利,与我而言,深受启发!

1.先序创建二叉树

#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 100//定义二叉树的结构体
typedef struct BiNode {char data;struct BiNode* lchild;struct BiNode* rchild;
}BiNode, * BiTree;//先序创建二叉树
BiTree CreateBiTree() {BiNode* T = NULL;char ch;ch = getchar();//先序输入树的各个节点值if (ch != '#') {T = (BiNode*)malloc(sizeof(BiNode));T->data = ch;T->lchild = CreateBiTree();T->rchild = CreateBiTree();}else {T = NULL;}return T;
}

2.非递归先序遍历二叉树

//非递归先序遍历二叉树
void PreOrder(BiTree T) {BiTree stack[MAXSIZE], node;//模拟栈int top = 0;if (T == NULL) {printf("树为空树!\n");return;}else {top++;stack[top] = T;while (top > 0) {//出栈node = stack[top--];printf("%c ", node->data);//先把右子树放进去,再放左子树,栈先进后出,左先出if (node->rchild != NULL) {stack[++top] = node->rchild;//入栈}if (node->lchild != NULL) {stack[++top] = node->lchild;}}}
}

3.非递归中序遍历二叉树 

//非递归中序遍历二叉树
void InOrder(BiTree T) {BiTree stack[MAXSIZE], node;int top = 0;if (T == NULL) {printf("树为空树!\n");return;}node = T;while (node != NULL || top > 0) {//将所有的左子树节点入栈while (node != NULL) {stack[++top] = node;node = node->lchild;}//此时指针指向节点的左孩子为空节点,访问节点node = stack[top--];printf("%c ", node->data);//指针指向右孩子node = node->rchild;}
}

4.非递归后序遍历二叉树 

//非递归后序遍历二叉树
void PostOrder(BiTree T) {BiNode* p = T;BiNode* stack[MAXSIZE];BiNode* r = NULL;//辅助指针,记录被访问过的节点int top = 0;while (p || top > 0) {  while (p) {     //走到最左边stack[top++] = p;p = p->lchild;}p = stack[top - 1]; //指针指向最后一个入栈的左节点if (NULL== p->rchild || p->rchild == r) {//此节点没有右孩子或者右孩子已经访问过printf("%c ", p->data);//访问该节点值top--;  r = p;  //记录最近访问过的节点p = NULL;   //节点访问完后重置p指针}else {p = p->rchild; //右孩子存在则指向右孩子,重复上面操作}}
}

5.非递归层序遍历二叉树 

//非递归层序遍历二叉树
void InvertLevel(BiTree T) {BiTree stack[MAXSIZE],node;//栈node = T;int front = 0;//模拟队列队头int rear = 0;//模拟队列队尾stack[rear++] = node;if (T == NULL) {printf("树为空树!\n");return;}while (front != rear) {//队列不为空node = stack[front++];//先获取队头元素,然后再指向队列的下一位元素printf("%c ", node->data);//访问节点元素if (node->lchild) {     stack[rear++] = node->lchild; //此节点左孩子不空,则入队列}if (node->rchild) {stack[rear++] = node->rchild; //此节点右孩子不空,则入队列}} //自上而下,从左到右依次遍历
}

6.非递归层序遍历求解二叉树的高度

//非递归层序遍历求解二叉树的高度
int TreeDepth(BiTree T) {if (!T)return 0;   //树空,高度为0BiTree Q[MAXSIZE];  //设置队列Qint front = -1, rear = -1;  //队头和队尾指针int last = 0,level = 0;    //last指向每层的最后一个节点的位置Q[++rear] = T;  //根节点入队BiTree p;   //工作指针while (front < rear) {  //队列不为空,则循环p = Q[++front]; //队列元素出队,对其进行访问if (p->lchild)Q[++rear] = p->lchild;  //左孩子入队if (p->rchild)Q[++rear] = p->rchild;  //右孩子入队if (front == last) {    //处理该层的最右结点level++;last = rear;    //last指向下一层}}return level;
}

 7.完整代码+测试运行

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 100//定义二叉树的结构体
typedef struct BiNode {char data;struct BiNode* lchild;struct BiNode* rchild;
}BiNode, * BiTree;//先序创建二叉树
BiTree CreateBiTree() {BiNode* T = NULL;char ch;ch = getchar();//先序输入树的各个节点值if (ch != '#') {T = (BiNode*)malloc(sizeof(BiNode));T->data = ch;T->lchild = CreateBiTree();T->rchild = CreateBiTree();}else {T = NULL;}return T;
}//非递归先序遍历二叉树
void PreOrder(BiTree T) {BiTree stack[MAXSIZE], node;//模拟栈int top = 0;if (T == NULL) {printf("树为空树!\n");return;}else {top++;stack[top] = T;while (top > 0) {//出栈node = stack[top--];printf("%c ", node->data);//先把右子树放进去,再放左子树,栈先进后出,左先出if (node->rchild != NULL) {stack[++top] = node->rchild;//入栈}if (node->lchild != NULL) {stack[++top] = node->lchild;}}}
}
//非递归中序遍历二叉树
void InOrder(BiTree T) {BiTree stack[MAXSIZE], node;int top = 0;if (T == NULL) {printf("树为空树!\n");return;}node = T;while (node != NULL || top > 0) {//将所有的左子树节点入栈while (node != NULL) {stack[++top] = node;node = node->lchild;}//此时指针指向节点的左孩子为空节点,访问节点node = stack[top--];printf("%c ", node->data);//指针指向右孩子node = node->rchild;}
}
//非递归后序遍历二叉树
void PostOrder(BiTree T) {BiNode* p = T;BiNode* stack[MAXSIZE];BiNode* r = NULL;//辅助指针,记录被访问过的节点int top = 0;if (T == NULL) {printf("树为空树!\n");return;}while (p || top > 0) {  while (p) {     //走到最左边stack[top++] = p;p = p->lchild;}p = stack[top - 1]; //指针指向最后一个入栈的左节点if (NULL== p->rchild || p->rchild == r) {//此节点没有右孩子或者右孩子已经访问过printf("%c ", p->data);//访问该节点值top--;  r = p;  //记录最近访问过的节点p = NULL;   //节点访问完后重置p指针}else {p = p->rchild; //右孩子存在则指向右孩子,重复上面操作}}
}
//非递归层序遍历二叉树
void InvertLevel(BiTree T) {BiTree stack[MAXSIZE],node;//栈node = T;int front = 0;//模拟队列队头int rear = 0;//模拟队列队尾stack[rear++] = node;if (T == NULL) {printf("树为空树!\n");return;}while (front != rear) {//队列不为空node = stack[front++];//先获取队头元素,然后再指向队列的下一位元素printf("%c ", node->data);//访问节点元素if (node->lchild) {     stack[rear++] = node->lchild; //此节点左孩子不空,则入队列}if (node->rchild) {stack[rear++] = node->rchild; //此节点右孩子不空,则入队列}} //自上而下,从左到右依次遍历
}
//非递归层序遍历求解二叉树的高度
int TreeDepth(BiTree T) {if (!T)return 0;   //树空,高度为0BiTree Q[MAXSIZE];  //设置队列Qint front = -1, rear = -1;  //队头和队尾指针int last = 0,level = 0;    //last指向每层的最后一个节点的位置Q[++rear] = T;  //根节点入队BiTree p;   //工作指针while (front < rear) {  //队列不为空,则循环p = Q[++front]; //队列元素出队,对其进行访问if (p->lchild)Q[++rear] = p->lchild;  //左孩子入队if (p->rchild)Q[++rear] = p->rchild;  //右孩子入队if (front == last) {    //处理该层的最右结点level++;last = rear;    //last指向下一层}}return level;
}
int main() {BiTree T = CreateBiTree();// BiTree T = create_tree();printf("非递归先序遍历二叉树:\n");PreOrder(T);printf("\n");printf("非递归中序遍历二叉树:\n");InOrder(T);printf("\n");printf("非递归后序遍历二叉树:\n");PostOrder(T);printf("\n");printf("非递归层序遍历二叉树:\n");InvertLevel(T);printf("\n");printf("非递归计算二叉树的深度为:\n");printf("树的深度为:%d\n", TreeDepth(T)); return 0;
}

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

  1. 数据结构二叉树中序遍历递归和非递归算法

    2022.11.19 二叉树中序遍历递归和非递归算法 任务描述 相关知识 编程要求 测试说明 C/C++代码 任务描述 本关任务:给定一棵二叉树,使用递归和非递归的方法实现二叉树的中序遍历结果. 相关 ...

  2. 二叉树先序遍历、中序遍历、后序遍历 递归和非递归算法

    一.二叉树先序遍历 (1)递归算法 // 递归先序遍历 public static void recursionPreorderTraversal(TreeNode root) {if (root ! ...

  3. 二叉树的后序遍历-递归和非递归算法

    同样的,创建的算法在先序中有,略去. 后序递归遍历算法 void PostOrder(BiTree bt){if(bt){PostOrder(bt->lchild);PostOrder(bt-& ...

  4. 二叉树的中序遍历-递归和非递归算法

    创建二叉树就不说了,这里直接: 中序递归遍历算法 void InOrder(BiTree T){if(T){InOrder(T->lchild);cout<<T->data&l ...

  5. 二叉树遍历【递归非递归】

    遍历代码 递归法 public class BinaryTreeTest {public static void main(String[] args) {System.out.println(&qu ...

  6. 【算法笔记】二叉树遍历模板递归+非递归

    目录 前序遍历 递归版本 迭代版本 中序遍历 递归版本 迭代版本 后序遍历 递归版本 迭代版本 二叉树层序遍历 栈的定义  语法注意: Deque<Integer> stack = new ...

  7. 二叉树的后序遍历(非递归算法)

    /*     后序遍历(非递归算法)     ①先序遍历顺序:根节点-左孩子-右孩子     ②后序遍历顺序:左孩子-右孩子-根节点     ③后序遍历倒过来:根节点-右孩子-左孩子     ①和③对 ...

  8. java使用btree_java数据结构之二叉树遍历的非递归实现

    算法概述 递归算法简洁明了.可读性好,但与非递归算法相比要消耗更多的时间和存储空间.为提高效率,我们可采用一种非递归的二叉树遍历算法.非递归的实现要借助栈来实现,因为堆栈的先进后出的结构和递归很相似. ...

  9. zz 递归算法转换为非递归算法

    from:http://blog.csdn.net/Shunrei/archive/2010/06/19/5680579.aspx 递归算法实际上是一种分而治之的方法,它把复杂问题分解为简单问题来求解 ...

  10. 递归算法向非递归算法转换

    递归算法向非递归算法转换 递归算法实际上是一种分而治之的方法,它把复杂问题分解为简单问题来求解.对于某些复杂问题(例如hanio塔问题),递归算法是一种自然且合乎逻辑的解决问题的方式,但是递归算法的执 ...

最新文章

  1. 论文笔记:Inception v1
  2. Cpp / 引用的本质
  3. MEDIATR 一个低调的中介者类库
  4. scanf(“%s“)真的只开读入字符串大小就可以了吗??
  5. 过滤器,绑定事件,动画
  6. snmp,mrtg安装和配置(2) mrtg安装
  7. java web 数据验证_kpvalidate开辟验证组件,通用Java Web请求服务器端数据验证组件...
  8. 计算机专业基础 -- 离散数学基础知识
  9. HTTP1.1 基础: 用C语言实现200行内的极简http server
  10. python的ols函数_Statsmodels OLS函数与虚拟变量Python
  11. k8s-linkerd
  12. Android App赞赏功能,微信公众号赞赏功能升级:作者可以直接收到赞赏
  13. html最快学会的方式,零基础HTML玩家的Bootstrap入门第一课(保证学会!)
  14. Apollo control模块纵向控制原理及核心代码逐行解析
  15. dingding钉钉 python接口
  16. 一文查看公信宝查封始末,CEO此前曾表示获利数千万
  17. 怎么申请电子邮箱账号?单位电子邮箱怎么申请?
  18. 什么是GMS、CDMA、GPRS、EDGE、WCDMA
  19. Cura软件的参数设置
  20. 构建需求响应式亿级商品详情页

热门文章

  1. 使用C++生成条形码
  2. Kafka权威指南,Kafka生产者
  3. arduino:废旧光驱DIY激光雕刻机(完善中……)
  4. 捷联惯导数值更新算法-姿态更新+速度更新+位置更新
  5. 【无人机】基于卡尔曼滤波实现无人机捷联惯导算法与组合导航附matlab代码
  6. 《yes!产品经理》(上册)读书笔记(完结)
  7. 通信原理matlab版,通信原理matlab
  8. 常用的Java开发工具
  9. AlphaGo的深度学习系统Tensorflow详细安装入门
  10. 什么是云计算机技术,云计算的核心技术是什么