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

news2024/11/27 14:35:42

目录

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

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

采用二叉链表的形式储存
结点结构 [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.coloradmin.cn/o/1599646.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

代码随想录算法训练营第四十二天| 二维背包、一维背包、LeetCode 416.分割等和子集

一、二维背包 文章讲解/视频讲解:https://programmercarl.com/%E8%83%8C%E5%8C%85%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%8001%E8%83%8C%E5%8C%85-1.html 状态:已解决 1.背包问题介绍 背包问题实则是一类问题的集合,有好多不同小类型&#xff0c…

Linux_iptables防火墙学习笔记

文章目录 iptables 概述四表五链iptables 安装启动iptables 配置详解iptables配置文件iptables配置语法iptables常用实例查看规则修改默认规则保存和备份规则恢复备份的规则清空规则放行SSH服务在ubuntu14.04中iptables规则持久化 iptables 概述 主机型 对主机进行保护 网络型…

Element-Ui的Form表单:Label文本两端对齐,且必填项的*不影响布局

1. HTML 结构 首先&#xff0c;确保你的 HTML 或 Vue 模板中有一个 el-form 组件&#xff0c;类似下面这样&#xff1a; <div id"app"><el-form :model"form" label-width"100px"><el-form-item label"用户名">&l…

Linux系统(centos,redhat,龙芯,麒麟等)忘记密码,怎么重置密码

Linux系统&#xff08;centos,redhat,龙芯&#xff0c;麒麟等&#xff09;忘记密码&#xff0c;怎么重置密码&#xff0c;怎么设置新的密码 今天在操作服务器时&#xff0c;DBA忘记了人大金仓数据库的kingbase密码&#xff0c;他的密码试了好多遍&#xff0c;都不行。最后只能…

JCVI-筛选blast最佳结果(生物信息学工具-015)

通常&#xff0c;大家会问我们经过了NR注释&#xff0c;SwissProt注释&#xff0c;那么如何进行&#xff0c;如何挑选最佳比对结果&#xff1f; 同理&#xff0c;存在一个问题&#xff0c;如何挑选最佳的blast比对结果&#xff1f;什么事最优的同源序列&#xff1f; 唐海宝老…

jenkins构建微信小程序并展示二维码

测试小程序的过程中&#xff0c;很多都是在回头和前端开发说一句&#xff0c;兄弟帮我打一个测试版本的测试码&#xff0c;开发有时间的情况下还好&#xff0c;就直接协助了&#xff0c;但是很多时候他们只修复了其中几个bug&#xff0c;其他需要修复的bug代码正在编写&#xf…

ENSP-旁挂式AC

提醒&#xff1a;如果AC不能成功上线AP&#xff0c;一般问题不会出在AC上&#xff0c;优先关注AC-AP线路上的二层或三层组网的三层交换机 拓扑图 管理VLAN&#xff1a;99 | 业务VLAN&#xff1a;100 注意点&#xff1a; 1.连接AP的接口需要打上pvid为管理vlan的标签 2.AC和…

引导和服务(2)

服务 1.systemd服务的简要介绍 &#xff08;1&#xff09;对比5 6 可以解决依赖关系并行启动 &#xff08;2&#xff09;按需启动 &#xff08;3&#xff09;自动解决依赖关系 负责在系统启动或运行时&#xff0c;激活系统资源&#xff0c;服务器进程和其它进程 2.System…

React-hooks:useReducer初始化函数 和 初始值 区别

useReducer 用法&#xff1a; const [state, dispatch] useReducer(reducer, initState, init?);其中&#xff0c;initialArg 为初始值&#xff08;必传&#xff09;&#xff0c;init 为初始函数&#xff08;可选&#xff09;。 当没有 init 参数时&#xff0c;state的初始…

Day56 动态规划 part16

Day56 动态规划 part16 583. 两个字符串的删除操作 我的思路&#xff1a; 感觉跟前两天子序列差不多&#xff0c;但是又有差别 这次是求删减最小次数&#xff0c;状态转移方程是比小 另外要注意初始化&#xff0c; 当i 0时&#xff08;word2为空&#xff09;&#xff0c;wor…

全球最新国内外18个热门风景视频素材网站推荐

寻找最新的高清风景视频素材&#xff1f;这里有国内外共18个热门网站&#xff0c;精心整理供您选择。 国内资源&#xff1a; 蛙学网&#xff1a;免费提供多种无版权视频素材&#xff0c;资源丰富。新GG网&#xff1a;需QQ登录&#xff0c;提供丰富的视频模板&#xff0c;通过…

从零开始写 Docker(十一)---实现 mydocker exec 进入容器内部

本文为从零开始写 Docker 系列第十一篇&#xff0c;实现类似 docker exec 的功能&#xff0c;使得我们能够进入到指定容器内部。 完整代码见&#xff1a;https://github.com/lixd/mydocker 欢迎 Star 推荐阅读以下文章对 docker 基本实现有一个大致认识&#xff1a; 核心原理&…

Java --- 类与对象

上篇内容给大家带来了Java的语句与数组的相关内容&#xff0c;那么本期内容比较重要&#xff0c;需要读者们掌握Java面向对象编程的根本&#xff0c;通过这篇博客来让读者浅入理解Java类的一些基本操作。 目录 一.特点&#xff1a; 二.成员变量&#xff1a; 三.访问修饰符&a…

工作流引擎项目解析

API 编辑 在Camunda中&#xff0c;API的继承关系主要体现在各个服务接口之间。以下是Camunda中一些常见服务接口的继承关系&#xff1a; ProcessEngineServices 接口&#xff1a; RepositoryService&#xff1a; 负责管理流程定义和部署。 RuntimeService&#xff1a; 负责管…

微信人脉扩张!多号批量自动加好友,你get到了吗?

微信是我们在拓展社交圈和寻找商业机会时&#xff0c;与更多的人建立联系的重要渠道。但是&#xff0c;手动一个个添加好友显然费时费力&#xff0c;这时候&#xff0c;微信管理系统的批量自动加好友功能就成为了微信人脉扩张的神器。 通过微信管理系统&#xff0c;我们可以轻…

思维导图ai生成软件分享5款好用的!

思维导图ai生成软件分享5款好用的&#xff01; 在快节奏的信息时代&#xff0c;思维导图作为一种有效的思维整理工具&#xff0c;越来越受到人们的青睐。它能够将复杂的思维过程可视化&#xff0c;帮助我们更好地梳理思路、规划工作。近年来&#xff0c;随着人工智能技术的飞速…

【笔记】探索生成范式:大型语言模型在信息提取中的作用

探索生成范式&#xff1a;大型语言模型在信息提取中的作用 摘要介绍 &#x1f308;你好呀&#xff01;我是 是Yu欸 &#x1f30c; 2024每日百字篆刻时光&#xff0c;感谢你的陪伴与支持 ~ &#x1f680; 欢迎一起踏上探险之旅&#xff0c;挖掘无限可能&#xff0c;共同成长&am…

实验六 智能手机互联网程序设计(微信程序方向)实验报告

实验目的和要求 请完成创建图片库应用&#xff0c;显示一系列预设的图片。 提供按钮来切换显示不同类别的图片。 二、实验步骤与结果&#xff08;给出对应的代码或运行结果截图&#xff09; 1.WXML <view> <button bindtap"showAll">所有图片</but…

闲不住,手写一个数据库文档生成工具

shigen坚持更新文章的博客写手&#xff0c;擅长Java、python、vue、shell等编程语言和各种应用程序、脚本的开发。记录成长&#xff0c;分享认知&#xff0c;留住感动。 个人IP&#xff1a;shigen 逛博客的时候&#xff0c;发现了一个很有意思的文章&#xff1a;数据库表结构导…

记录一下我hive连不上DataGrip的问题

用户名和密码都没问题&#xff0c;但报如下这个错误 原因&#xff1a;是因为我在linux上没启hiveserver2服务 解决&#xff1a; [atguiguhadoop102 hadoop]$ hiveserver2 which: no hbase in (/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/opt/module/jdk1.8…