【数据结构】遍历二叉树(递归和非递归遍历的先序、中序和后序遍历、层次遍历法)

目录

  • 【数据结构】遍历二叉树(递归和非递归遍历的先序、中序和后序遍历、层次遍历法)
    • 一、递归算法
      • 先(根)序的遍历算法
      • 中(根)序的遍历算法
      • 后(根)序的遍历算法
    • 二、非递归算法
      • 层次遍历
      • 先序遍历非递归算法
      • 中序遍历非递归算法
      • 后序遍历非递归算法

【数据结构】遍历二叉树(递归和非递归遍历的先序、中序和后序遍历、层次遍历法)

采用二叉链表的形式储存
结点结构 [lchild,data,rchild]

特点:二叉链表找子孙结点容易,找祖先结点麻烦。

typedef struct BiTNode {                char data;  struct BiTNode *lchild, *rchild; //左右子树根结点地址
} BiTNode, *BiTree;

一、递归算法

递归算法书写简单,但是效率低。

先(根)序的遍历算法

先序遍历(递归定义 递归结束的条件就是:空树 )

  1. 若二叉树为空树,则空操作;
  2. 否则,(1)访问根结点;(2)先序遍历左子树;(3)先序遍历右子树。

先序遍历的递归算法:

//先序遍历 递归访问每一个结点
void xxbl(BiTree T){if(T){//递归调用的结束条件printf("%c",T->data);//访问结点xxbl(T->lchild);//遍历左子树xxbl(T->rchild);//遍历右子树}
}

中(根)序的遍历算法

  1. 若二叉树为空树,则空操作;
  2. 否则,(1)中序遍历左子树;(2)访问根结点;(3)中序遍历右子树。

中序遍历的递归算法:

void zxbl(BiTree T)
{if (T) {zxbl(T->lchild); printf("%c",T->data); zxbl(T->rchild);}
}

后(根)序的遍历算法

  1. 若二叉树为空树,则空操作;
  2. 否则,(1)后序遍历左子树;(2)后序遍历右子树;(3)访问根结点。
void hxbl(BiTree T)
{if(T){hxbl(T->lchild); hxbl(T->rchild); printf("%c",T->data);}
}

二、非递归算法

  1. 用循环队列实现二叉树的按层次遍历
  2. 使用 来实现 先保存 后 访问

层次遍历

从根节点开始,先访问第一层的结点,在访问第二层的结点。
特点:自顶向下,从左到右的访问次序。
借用 队列(循环队列) 来实现层次遍历的功能,所有要访问的结点都存放在队列中。

  1. 初始时若二叉树非空,则只需要知道要访问的第一个结点为根结点。
  2. 只要队列不空,说明队列中存有要访问的结点,则取队首结点访问,并将其非空左右孩子依次插入队列中。
    在这里插入图片描述
    算法代码示例:
//层次遍历算法
#define MAX 100
void LevelTrave(BiTree T){BiTree Q[MAX],p;//用循环队列实现二叉树的按层次遍历int f=r=0;//队列 队首和队尾指针if(T==NULL)	return;Q(r++)=T;// 根节点入队while(f!=r){p=Q[f++];//出队printf("%c",p->data);if(p->lchild){if(r>=MAX){printf("overflow");exit(0);}Q[r++]=p->lchild;}if(p->rchild){if(r>=MAX){printf("overflow");exit(0);}Q[r++]=p->rchild;}}
}

先序遍历非递归算法

先序遍历非递归算法的实现:访问根节点后,在访问左子树之前,先将其非空右子树的地址入栈(保存)。
在这里插入图片描述
采用顺序栈来存放访问过的结点右子树:

#define MAX 10000
typedef struct{BiTree data[MAX];int top;
}SeqStack;
void PreorderTraverse(BiTree T){//T为二叉树的根结点SeqStack s;//新建一个 栈BiTree p;s.top=-1; //栈顶指针p = T;//while(p){while(p){//访问左子树printf("%c",p->data); //访问p结点if(p->rchild) {//将p结点的非空右孩子入栈保存if(s.top==MAX-1) exit (0);//栈溢出else s.data[++s.top]=p->rchild;//入栈}p =p->lchild; //访问p的左孩子  }if (s.top!=-1) p=s.data[s.top--];//出栈}
}

中序遍历非递归算法

  1. 基本思想:访问根结点的左子树前,应保存其根结点,以便左子树访问结束后,访问根和根的右子树
  2. 图中a结点先于b结点被保存,但是其访问要在b及b的右子树被访问后进行----先保存后访问----先进后出----借助栈来实现

在这里插入图片描述

void InorderTraverse(BiTree T){//中序遍历根结点为T的二叉树SeqStack s; BiTree p;s.top=-1; p = T;while(p||(s.top!=-1)){ //while(p){if(s.top==MAX-1) exit (0);s.data[++s.top]=p; p =p->lchild;// 一直去访问左子树 同时将结点入栈//向左下走一直走到头}if (s.top!=-1){p=s.data[s.top--];//根节点出栈printf("%c",p->data);p = p->rchild; //访问该根节点的右子树}}
}

后序遍历非递归算法

  1. 后序遍历非递归算法的实现:访问根结点的子树前,应保存其根结点,以便左子树访问结束后,访问根的右子树和根
  2. 图中a结点先于b结点被保存,但是其访问要在b及其右子树被访问后进行----先保存后访问----先进后出----借助栈实现

只有在其左、右子树被访问后才能被访问(需要标记 定义一个flag标记其左右子树是否都被访问过)
在这里插入图片描述

#define	MAX5
typedef struct{BiTree q;int flag;
}dataelem;
//q存放的是遍历操作访问到的一棵子树的根节点
//flag=0代表目前是在访问q结点的左子树,flag=1代表目前是在访问q结点的右子树
typedef struct{
dataelem data[MAX];
int top;//栈顶指针
}SeqStack2;

代码示例(!!!):

void postorder(BiTree T){SeqStack2 s;s.top=-1;p=T;do{while(p!=NULL){if(s.top==MAX-1) exit (0);//栈溢出s.data[++s.top].q=p; s.data[s.top].flag=0; p=p->lchild;//一直向左下访问 }while((s.top>-1)&&(s.data[s.top].flag==1)){ //p=s.data[s.top--].q; printf(%c”,p->data); }if(s.top>-1){s.data[s.top].flag=1;//标记 此时开始访问 其右子树p=s.data[s.top].q; p=p->rchild;}}while(s.top>-1);
}

感谢阅读!!!

  1. 树与二叉树知识点文章: 【数据结构】树与二叉树(递归法先序、中序、后序、层次遍历二叉树、二叉树的建立以及求树高的方法)
  2. 二叉树遍历算法的应用: 【数据结构】树与二叉树遍历算法的应用(求叶子节点个数、求树高、复制二叉树、创建二叉树、二叉树存放表达式、交换二叉树每个结点的左右孩子)
  3. 二叉树遍历算法的应用: 【数据结构】树与森林(树的存储结构、森林与二叉树的转化、树与森林的遍历)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/623905.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【vue】Pinia-2 安装Pinia,使用store

1. 安装Pinia 在项目路径下执行npm install pinia 在package.json中查看 2. 使用store 在main.js中添加 import { createPinia } from pinia const pinia createPinia()修改createApp方法 最后示例如下(三处修改) import { createApp } from vue //…

JRT多服务器同步程序

之前的JRT只部署在一个服务器,实际运用可能会有数台、数十台、或者更多服务器。那么多台服务器就需要程序同步机制。这里借助Rsync同步,但是有个问题是Rsync同步jar之后他不知道是否需要重启站点,为此实现java控制台驱动Rsync,重定…

车载摄像头畸变校正解决方案,打造无畸变高清视界

在车载摄像头日益普及的今天,摄像头图像的畸变问题成为了制约图像质量提升的一大瓶颈。畸变不仅影响画面的美观度,更关键的是它可能导致智能驾驶系统对环境的误判,进而威胁到行车安全。美摄科技凭借其在图像处理领域的深厚实力,推…

cpcie和cpci差别

CPCI总线 •PCI总线作为处理器系统的局部总线,主要目的是为了连接外部设备,而不是作为处理器的系统总线连接Cache和主存储器 •(1) PCI总线空间与处理器空间隔离 •(2) 可扩展性 桥 •(3) 动态配置机制即插即用 •(4) 总线带宽 •(5) 共享总线机制 •…

2024年nodejs调用小红书最新关注(粉丝)follow接口,api接口分析2004-04-16

一、打开chrome按f12,点击右上角的“关注”按钮,抓包位置如下: (图1 follow接口) 二、follow接口分析 1、请求地址 https://edith.xiaohongshu.com/api/sns/web/v1/user/follow 2、请求方法: POST 3、请求头: :authority: edith…

Web3.0与AI的交融:开启智能互联网新时代

目前有140 多个 Web3 AI 概念项目,覆盖了基础设施、数据、预测市场、计算与算力、教育、DeFi & 跨链、安全、NFT & 游戏 & 元宇宙、搜索引擎、社交 & 创作者经济、AI 聊天机器人、DID & 消息传递、治理、医疗、交易机器人等诸多方向。持续关注…

MongoDB的go SDK使用集锦

在上一章解读MongoDB官方文档获取mongo7.0版本的安装步骤与基本使用介绍了如何使用mongo shell操作mongo数据库,接下来介绍如何使用sdk来操作数据库,这里以go语言为例,其他语言请查看源文档mongo docs Quick Start 内置数据结构 MongoDB是存…

关于idea中mybatis插件,下载后,无法生成代码模板--解决方法

一、不用相信网上其他解决方法 1.1试过,无效 二、解决方法 2.1【注:多试几次】重新下载,并重新启动idea 三、操作方法 3.1步骤 3.2idea重启,【如果没有重启】手动重启,必须有,很重要 3.3重新下载mybat…

电商技术揭秘九:搜索引擎中的SEO数据分析与效果评估

相关系列文章 电商技术揭秘一:电商架构设计与核心技术 电商技术揭秘二:电商平台推荐系统的实现与优化 电商技术揭秘三:电商平台的支付与结算系统 电商技术揭秘四:电商平台的物流管理系统 电商技术揭秘五:电商平台的个性…

【触想智能】如何选购到一款合适的工业电脑一体机

工业电脑一体机是专为工业环境而设计的一种工业计算机。工业电脑一体机和普通的计算机不一样,它对产品的参数性能要求很高,因为它们通常会运行在高低温、电磁干扰、高粉尘、湿度大的恶劣环境中,所以相应的要求工业电脑一体机必须具备良好的宽…

47.HarmonyOS鸿蒙系统 App(ArkUI)创建轮播效果

创建轮播效果,共3页切换 Entry Component struct Index {State message: string Hello Worldprivate swiperController: SwiperController new SwiperController()build() {Swiper(this.swiperController) {Text("第一页").width(90%).height(100%).bac…

记第一次踩坑Gradle

今天有个项目只能使用Gradle编译,没办法了,尝试吧。 先去下载了最新版本的Gradle,然后配置好了环境变量,可以在命令行使用gradle命令了。 然后打开项目开始操作一番,但是上来就傻眼了。 我白下载了,又重新下…