二叉树的递归遍历及非递归遍历
二叉树的基本操作——创建、输出、查找、删除_yyy_zxc的博客-CSDN博客_二叉树的创建与输出创建二叉树过程:/*-----------第一轮循环:ch = A;p->data保存结点值b==NULL,b=p将p保存为根结点ch = (第二轮循环:top = 0;St[0] = p = A ,St保存上一个结点k=1ch = B第三轮循环:p->data保存结点值根据上一轮循环的k值判断ch为左孩子还是右孩子,k=1所以将 p保存为左孩子https://blog.csdn.net/yyy_zxc/article/details/124154037
#include"tree.cpp" //包含了二叉树的基本算法//---------------------先序遍历---------------
/*根 --左 --右*/
void Preorder(BTNode *b){if(b!=NULL){printf("%c",b->data); //访问结点Preorder(b->lchild); //递归遍历左子树 Preorder(b->rchild); // 递归遍历右子树 }
} //-----非递归遍历算法
void Preorder1(BTNode *b){BTNode *St[MaxSize],*p; //St[]为存储双亲结点的栈 int top = -1; //栈顶指针 if(b!=NULL){top++; St[top] = b; //根结点进栈while(top>-1){ //栈空时结束循环p=St[top]; //退栈并访问该节点top--;printf("%c",p->data); //访问结点if(p->rchild != NULL){ //有右孩子,将其进栈top++;St[top] = p->rchild; }if(p->lchild != NULL ){ //有左孩子,将其进栈top++;St[top] = p->lchild; } //右孩子先进栈,利用的是栈先进后出的原理 } }printf("\n");
} //------------中序遍历--------------
//左 根 右//递归遍历
void Inorder(BTNode *b){if(b!=NULL){Inorder(b->lchild);printf("%c",b->data); //访问结点Inorder(b->rchild); // 递归遍历右子树 }
} //非递归遍历
void Inorder1(BTNode *b){BTNode *St[MaxSize],*p;int top=-1;if(b != NULL){p=b;while(top>-1 || p!= NULL){while(p!=NULL){ //扫描p结点下的所有左子树,并进栈 ,p也进栈 top++;St[top] = p; p = p->lchild;}//此时已经退出第二层循环 if(top>-1){p=St[top]; //p结点出栈,并访问top--;printf("%c",p->data);p = p->rchild; //p指向右孩子 }}printf("\n");}
} //--------------后序遍历 ---------
// 左---右---根//递归遍历
void Postorder(BTNode *b){if(b != NULL){Postorder(b->lchild); //递归调用左子树Postorder(b->rchild);printf("%c",b->data); //访问根结点 }
} //非递归遍历void Postorder2(BTNode *b){BTNode *St[MaxSize],*p;int top=-1;bool flag;if(b!=NULL){do{while(b!=NULL){ //遍历b结点左子树 top++;St[top] =b;b = b->lchild;}p=NULL; //p指向当前结点的前一个已访问的结点flag = true; //flag为真表示正在处理栈顶结点while(top!=-1 && flag){b = St[top]; //取出当前的栈顶元素if(b->rchild==p){ //若右子树不存在或已被访问,则访问该结点 printf("%c",b->data); //访问b结点top--;p = b; //p指向被访问的结点 } else{b=b->rchild; //b指向右子树flag=false; //表示当前不是处理栈顶结点 } } }while(top!=-1);printf("\n");}}//层次遍历
/*
算法思想:
1、初始化一个辅助队列
2、根结点入队【存的是指针而不是结点本身,所以是 Qu[rear] = b;而不是 Qu[rear] = b->data;】
3、若队列非空,则队头结点出队,访问该结点,并将该结点的左右孩子插入队尾
4、重复,直到队列为空
*/ void TravLevel(BTNode *b){BTNode *Qu[MaxSize]; //定义环形队列int front,rear; //定义队首和队尾指针front = rear =0; //初始化队列
// if(b!=NULL)
// printf("%c",b->data); //访问根结点rear++;Qu[rear] = b; //根结点进队while(rear != front){ //队列不为空front = (front + 1)%MaxSize; //队头结点出队,并访问该结点 b = Qu[front]; //front指向结点已出队 printf("%c",b->data);if(b->lchild != NULL){ //若有左孩子,将左孩子入队rear = (rear+1)%MaxSize;Qu[rear] = b->lchild;} if(b->rchild != NULL){ //若有右孩子,将右孩子入队rear = (rear+1)%MaxSize;Qu[rear] = b->rchild;} } printf("\n");
} /*
方法二1、初始化一个辅助队列
2、访问根结点,并入队【存的是指针而不是结点本身】
3、若队列非空,则队头结点出队,访问该结点的左右孩子,并将左右孩子插入队尾
4、重复,直到队列为空
*/void TravLevel01(BTNode *b){BTNode *Qu[MaxSize];int front,rear;front = rear = 0;if(b!=NULL)printf("%c",b->data);rear++;Qu[rear] = b; while(rear != front){front = (front+1)%MaxSize;b = Qu[front];if(b->lchild != NULL){printf("%c",b->data);rear = (rear+1)%MaxSize;Qu[rear] = b->lchild;} if(b->rchild!=NULL){printf("%c",b->data);rear = (rear+1)%MaxSize;Qu[rear] = b->rchild;}}printf("\n");
}int main(){BTNode *b;printf("创建二叉树\n");CreatBTree(b,"A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I))");printf("输出二叉树"); DispBTree(b);printf("\n"); printf("层次遍历二叉树:\n");printf("方法一:");TravLevel(b);printf("方法二:");TravLevel01(b);printf("-----先序遍历二叉树:\n");printf("递归:");Preorder(b);printf("\n");printf("非递归:");Preorder1(b);printf("-----------中序遍历二叉树:\n");printf("递归:");printf("\n");Inorder(b);printf("非递归:");Inorder1(b);printf("---------------------后序遍历二叉树:\n");printf("递归:");printf("\n");Postorder(b);printf("非递归:");Postorder2(b);printf("释放二叉树\n");DestroyBTree(b);return 1;
}
二叉树的递归遍历及非递归遍历相关推荐
- 漫谈二叉树遍历(非递归)
------这篇文章旨在提出一种简单方便,易于理解时空复杂度低且风格统一的二叉树非递归遍历方法. 从二叉树先序遍历开始 二叉树的先序遍历(非递归)相比中后序是最少花哨.最统一的.一般来说先序遍历的代码 ...
- 4.二叉树的先序、中序以及后序遍历的递归写法与非递归写法(LeetCode第94、144、145题)
一.递归法 这次我们要好好谈一谈递归,为什么很多同学看递归算法都是"一看就会,一写就废". 主要是对递归不成体系,没有方法论,每次写递归算法 ,都是靠玄学来写代码,代码能不能编过都 ...
- 遍历二叉树的各种操作(非递归遍历)
先使用先序的方法建立一棵二叉树,然后分别使用递归与非递归的方法实现前序.中序.后序遍历二叉树,并使用了两种方法来进行层次遍历二叉树,一种方法就是使用STL中的queue,另外一种方法就是定义了一个数组 ...
- 二叉树路径应用举例(基于非递归后序遍历)
#include "stdafx.h" #include <iostream> #include <fstream>using namespace std; ...
- 算法练习day10——190328(二叉树的先序、 中序、 后序遍历, 包括递归方式和非递归方式、找到一个节点的后继节点、二叉树的序列化和反序列化)
1.实现二叉树的先序. 中序. 后序遍历, 包括递归方式和非递归方式 1.1 访问节点的顺序 节点访问顺序如下图所示: 访问顺序:1 2 4 4 4 2 5 5 5 2 1 3 6 6 6 3 7 7 ...
- 信号放大器数据结构_[11/11]数据结构 二叉树应用(树型信号放大器,file transfer,遍历的非递归实现)...
树型分布网络信号放大器 森林和二叉树的相互转换 并查集 例题:File transfer #include <iostream> using namespace std; //typede ...
- 二叉树前序、中序和后序遍历的非递归实现
1 二叉树的遍历 1.1 前序遍历 对于每棵子树,先处理根,然后处理左子树,最后处理右子树.根最先访问,所以是前序遍历. 1.2 中序遍历 对于每棵子树,先处理左子树,然后处理根,最后处理右子树.根中 ...
- 二叉树先中后序递归遍历与非递归遍历、层次遍历
文章目录 1 先序遍历 1.1 先序遍历递归 1.2 先序遍历非递归 2 中序遍历 2.1 中序遍历递归 2.2 中序遍历非递归 3 后序遍历 3.1 后序遍历递归 3.2 后序遍历非递归 4 层序遍 ...
- 二叉树前中后序遍历的非递归实现以及层次遍历、zig-zag型遍历详解
前言 二叉树的遍历是一个比较常见的问题,递归实现二叉树的前中后序遍历比较简单,但非递归实现二叉树的前中后序遍历相对有难度.这篇博客将详述如何使用非递归的方式实现二叉树的前中后序遍历,在进行理论描述的同 ...
- 二叉树的遍历(非递归)整理
二叉树的遍历(非递归) 写在前面 二叉树重要,重要,重要.以下代码每日手撸一遍,深刻理解. 二叉树的先序遍历(非递归) 巧记心法 判断是否为空树 1.右侧入栈(访问,q指向右孩子,不空则入栈) 2.p ...
最新文章
- apache2.4中layout模块和ssi模块的冲突
- python网络编程教学_python网络编程学习初步
- 1-1圆柱体的表面积(算法竞赛入门经典)
- zmail邮件系统安装手册 V2.0版本
- php中metadata,模型元数据(Models Metadata)
- ERwin 正向工程
- 互联网项目架构经验分享
- 创建类模式(零):简单/静态工厂(Static Factory)
- 图(graph)神经网络学习(四)--代码解析(Model_2)
- vue —— 利用 viewport 进行适配
- 微信小程序系列(5)如何用微信小程序写一个论坛?贴心代码详解(三)列表页
- ios 国外账户的创建
- oracle10G 异构方式迁移表空间之二
- 鲁大师2022牛角尖颁奖盛典落幕,年度最强产品揭晓!
- 模式识别——初识模式识别
- linux佳能打印机服务,linux桌面打印机配置指南
- 明天是程序员节,程序员的过节姿势大全抢先看
- 一个apk通过隐式Intent 启动另一个apk
- 计算机书籍旧版好还是新版好,新固件还不如老版本好用?教你如何禁止Kindle自动更新!...
- 抽象类与接口有什么异同?