二叉树遍历的一些非递归算法
二叉树的非递归算法因为涉及到栈和队列,所以写的时候总是受到伪代码的干扰,要完整的补全栈和队列的结构有些麻烦,这里借鉴了一些大佬的思想,发现可以直接在树中模拟栈和队列的存在,这给非递归的完整代码带来了很大的便利,与我而言,深受启发!
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;
}
二叉树遍历的一些非递归算法相关推荐
- 数据结构二叉树中序遍历递归和非递归算法
2022.11.19 二叉树中序遍历递归和非递归算法 任务描述 相关知识 编程要求 测试说明 C/C++代码 任务描述 本关任务:给定一棵二叉树,使用递归和非递归的方法实现二叉树的中序遍历结果. 相关 ...
- 二叉树先序遍历、中序遍历、后序遍历 递归和非递归算法
一.二叉树先序遍历 (1)递归算法 // 递归先序遍历 public static void recursionPreorderTraversal(TreeNode root) {if (root ! ...
- 二叉树的后序遍历-递归和非递归算法
同样的,创建的算法在先序中有,略去. 后序递归遍历算法 void PostOrder(BiTree bt){if(bt){PostOrder(bt->lchild);PostOrder(bt-& ...
- 二叉树的中序遍历-递归和非递归算法
创建二叉树就不说了,这里直接: 中序递归遍历算法 void InOrder(BiTree T){if(T){InOrder(T->lchild);cout<<T->data&l ...
- 二叉树遍历【递归非递归】
遍历代码 递归法 public class BinaryTreeTest {public static void main(String[] args) {System.out.println(&qu ...
- 【算法笔记】二叉树遍历模板递归+非递归
目录 前序遍历 递归版本 迭代版本 中序遍历 递归版本 迭代版本 后序遍历 递归版本 迭代版本 二叉树层序遍历 栈的定义 语法注意: Deque<Integer> stack = new ...
- 二叉树的后序遍历(非递归算法)
/* 后序遍历(非递归算法) ①先序遍历顺序:根节点-左孩子-右孩子 ②后序遍历顺序:左孩子-右孩子-根节点 ③后序遍历倒过来:根节点-右孩子-左孩子 ①和③对 ...
- java使用btree_java数据结构之二叉树遍历的非递归实现
算法概述 递归算法简洁明了.可读性好,但与非递归算法相比要消耗更多的时间和存储空间.为提高效率,我们可采用一种非递归的二叉树遍历算法.非递归的实现要借助栈来实现,因为堆栈的先进后出的结构和递归很相似. ...
- zz 递归算法转换为非递归算法
from:http://blog.csdn.net/Shunrei/archive/2010/06/19/5680579.aspx 递归算法实际上是一种分而治之的方法,它把复杂问题分解为简单问题来求解 ...
- 递归算法向非递归算法转换
递归算法向非递归算法转换 递归算法实际上是一种分而治之的方法,它把复杂问题分解为简单问题来求解.对于某些复杂问题(例如hanio塔问题),递归算法是一种自然且合乎逻辑的解决问题的方式,但是递归算法的执 ...
最新文章
- 论文笔记:Inception v1
- Cpp / 引用的本质
- MEDIATR 一个低调的中介者类库
- scanf(“%s“)真的只开读入字符串大小就可以了吗??
- 过滤器,绑定事件,动画
- snmp,mrtg安装和配置(2) mrtg安装
- java web 数据验证_kpvalidate开辟验证组件,通用Java Web请求服务器端数据验证组件...
- 计算机专业基础 -- 离散数学基础知识
- HTTP1.1 基础: 用C语言实现200行内的极简http server
- python的ols函数_Statsmodels OLS函数与虚拟变量Python
- k8s-linkerd
- Android App赞赏功能,微信公众号赞赏功能升级:作者可以直接收到赞赏
- html最快学会的方式,零基础HTML玩家的Bootstrap入门第一课(保证学会!)
- Apollo control模块纵向控制原理及核心代码逐行解析
- dingding钉钉 python接口
- 一文查看公信宝查封始末,CEO此前曾表示获利数千万
- 怎么申请电子邮箱账号?单位电子邮箱怎么申请?
- 什么是GMS、CDMA、GPRS、EDGE、WCDMA
- Cura软件的参数设置
- 构建需求响应式亿级商品详情页