二叉树创建和遍历

个人主页    :敲上瘾-CSDN博客
二叉树介绍:二叉树(详解)-CSDN博客

目录

一、二叉树的创建

二、二叉树的遍历

1.前序遍历

2.中序遍历

3.后序遍历

4.层序遍历

三、相关计算

1.总节点个数计算

2.叶子节点个数计算

3.深度计算


一、二叉树的创建

        关于二叉树的创建和遍历我们考虑用递归来实现。
        我们通过前序遍历的数组"ABD##E#H##CF##G##" 来创建数组,其中 '#' 相当于空指针。

头文件的声明:

typedef char BTDataType;typedef struct BinaryTreeNode
{BTDataType _data;struct BinaryTreeNode* _left;struct BinaryTreeNode* _right;
}BTNode;
BTNode* BinaryTreeCreate(BTDataType* a, int n, int* pi)
{if (*pi == n)return NULL;int val = a[(*pi)++];if (val == '#')return NULL;BTNode* root = (BTNode*)malloc(sizeof(BTNode));assert(root);root->_data = val;root->_left = BinaryTreeCreate(a, n, pi);root->_right = BinaryTreeCreate(a, n, pi);return root;
}

二、二叉树的遍历

        学习二叉树结构,最简单的方式就是遍历。所谓二叉树遍历(Traversal)是按照某种特定的规则,依次对二叉树中的结点进行相应的操作,并且每个结点只操作一次。访问结点所做的操作依赖于具体的应用问题。

        遍历是二叉树上最重要的运算之一,也是二叉树上进行其它运算的基础。
按照规则,二叉树的遍历有:前序/中序/后序的递归结构遍历:
        1. 前序遍历(Preorder Traversal 亦称先序遍历)——访问根结点的操作发生在遍历其左右子树之前。
        2. 中序遍历(Inorder Traversal)——访问根结点的操作发生在遍历其左右子树之中(间)。
        3. 后序遍历(Postorder Traversal)——访问根结点的操作发生在遍历其左右子树之后。
由于被访问的结点必是某子树的根,所以N(Node)、L(Left subtree)和R(Right subtree)又可解释为根、根的左子树和根的右子树。NLR、LNR和LRN分别又称为先根遍历、中根遍历和后根遍历。

1.前序遍历

void BinaryTreePrevOrder(BTNode* root)
{if (!root){printf("#");return;}printf("%c", root->_data);BinaryTreePrevOrder(root->_left);BinaryTreePrevOrder(root->_right);
}
//或者这么写:
void PrevOrder(BTNode* root)
{if (root){printf("%c", root->_data);PrevOrder(root->_left);PrevOrder(root->_right);}
}

2.中序遍历

void BinaryTreeInOrder(BTNode* root)
{if (!root){printf("#");return;}BinaryTreeInOrder(root->_left);printf("%c", root->_data);BinaryTreeInOrder(root->_right);
}

3.后序遍历

void BinaryTreePostOrder(BTNode* root)
{if (!root){printf("#");return;}BinaryTreePostOrder(root->_left);BinaryTreePostOrder(root->_right);printf("%c", root->_data);
}

4.层序遍历

        层序遍历是一层一层往下遍历的,并不是单个方向深入,像以上三种遍历都可以叫做深度优先遍历,而层序遍历也可以叫做广度优先遍历,它是不能用递归实现的,要实现它我们可以使用一个队列结构,我们把根节点存入队列然后对队列进行操作,把根节点拿出来(Pop)然后把它的左孩子和右孩子依次取出放入队列,然后再次从队头取到根节点重复操作,一次下去直到队列为空,就能完成层序遍历。如下:

void BinaryTreeLevelOrder(BTNode* root)
{if (!root)return;Queue pt;//需要构造出一个队列结构,这里就不在展示QueueInit(&pt);QueuePush(&pt, root);while (!QueueEmpty(&pt)){BTNode* pf = QueueFront(&pt);if (pf)printf("%c", pf->_data);elseprintf("#");QueuePop(&pt);if (pf){QueuePush(&pt, pf->_left);QueuePush(&pt, pf->_right);}}
}

三、相关计算

1.总节点个数计算

        在计算节点个数的时候,初学着可能会想用一个全局变量,用以上任意方法遍历并计数。这种方法是可行的但不太可靠。像这些二叉树相关的计算我们大多数都可以考虑把它化为小问题去分析。如果是空树的话就是0,如果不是空树就是1+左树的节点个数+右树的节点个数,像这样左树又可以分为左树和右树去解决,可以不断的把问题化小。如下:

int BinaryTreeSize(BTNode* root)
{if (!root)return 0;elsereturn BinaryTreeSize(root->_left) + BinaryTreeSize(root->_right) + 1;
}

2.叶子节点个数计算

这个计算和上一个方法是相似的,不过我们得特别判断以下是否为叶子节点。如下:

int BinaryTreeLeafSize(BTNode* root)
{if (!root)return 0;if (!root->_left && !root->_right)return 1;return BinaryTreeLeafSize(root->_left) + BinaryTreeLeafSize(root->_right);
}

3.深度计算

        求一颗树的深度可以化为就是左子树的深度和右子树中的最大深度,而左子树又可以在化为更小的左右子树的深度就如此递推下去,直到遇到空树才一次回归(返回),这样就把大问题化为小问题用递归实现。如下:

int BinaryTreeHeight(BTNode* root)
{if (!root)return 0;int v1=BinaryTreeHeight(root->_left);int v2 = BinaryTreeHeight(root->_right);return v1 > v2 ? v1 + 1 : v2 + 1;
}

要注意一点的是千万不要写成下面的方式: 

这样会使一个函数内就有三个递归展开,效率会变得非常非常低。 

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

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

相关文章

如何在路由器上安装代理服务:详细教程

如何在路由器上安装代理服务:详细教程 步骤一:通过漏洞进入路由器系统开启Telnet服务使用Telnet登录路由器系统查看系统信息和CPU信息步骤二:交叉编译MIPS程序 Go对MIPS的支持 安装TFTP Server使用BusyBox tftp传输文件在路由器系统中下载编译…

❤机器学习正则化算法的总结。耗时10个小时完成。❤

❤纯 干 货~❤ 目录 纯干货 1、L1 正则化(Lasso 正则化) 2、L2 正则化(岭正则化) 3、弹性网络正则化(Elastic Net 正则化) 4、Dropout 正则化(用于神经网络) 5、贝叶斯Rid…

海外盲盒小程序:跨文化营销的利器

在全球化的浪潮下,跨境电商正迎来前所未有的发展机遇。作为这一领域中的新兴力量,海外盲盒小程序凭借其独特的魅力和优势,正逐渐崭露头角,成为跨文化营销的利器。本文将探讨海外盲盒小程序在跨文化营销中的应用及其带来的价值。 一…

【30天精通Prometheus:一站式监控实战指南】第16天:snmp_exporter从入门到实战:安装、配置详解与生产环境搭建指南,超详细

亲爱的读者们👋   欢迎加入【30天精通Prometheus】专栏!📚 在这里,我们将探索Prometheus的强大功能,并将其应用于实际监控中。这个专栏都将为你提供宝贵的实战经验。🚀   Prometheus是云原生和DevOps的…

【java11】java11新特性之增强String的API

Java11在String类上引入了一系列新的API增强,这些改进显著提升了开发者在处理字符串时的便捷性和效率。 以下是Java11中增强String API的主要新特性: String.repeat():重复给定次数的字符串。返回连接的字符串。String.isBlank()&#xff1…

ldap协议(常用于统一身份认证)与dict协议(在线词典)

文章目录 LDAPDICT LDAP LDAP(Light Directory Access Portocol),轻量目录访问协议。 目录是一个为查询、浏览和搜索而优化的数据库,它成树状结构组织数据,类似文件目录一样。 目录数据库和关系数据库不同&#xff0c…

spring security 使用记录

spring security 使用记录 Bad credentials配置类密码匹配 Bad credentials org.springframework.security.authentication.BadCredentialsException: Bad credentialsat org.springframework.security.authentication.dao.DaoAuthenticationProvider.additionalAuthenticatio…

Docker安装极简版(三分钟搞定)

什么是Docker? Docker是一个开源的应用容器引擎,它允许开发者打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。 化。容器是…

日志脱敏功能

前言 数据安全尤为重要,最为简单的防线就是防止重要信息(身份证、手机号、姓名等)明文显示,对此需要在数据库层、日志层等做好数据加解密。 思路 1、编写需加密的正则模板、加密字段 2、重写ch.qos.logback.classic.pattern.Me…

简易图像处理器的设计

1 概述 Python是一种高级、通用、解释型的编程语言,由Guido van Rossum于1991年创造。它被设计为易读易写的语言,具有简洁而清晰的语法,使得它成为许多领域的首选语言,如Web开发、科学计算、人工智能、数据分析等。结合本科阶段以…

三维地图校内导航系统解决方案

在如今的数字化时代,越来越多的学校开始实施智慧校园计划,旨在为学生和教师提供更高效、便捷的学习和教学环境。智慧校园运用互联网、大数据、人工智能等技术,对校园内各信息进行收集、整合、分析和应用,实现教学、管理、服务等多…

【matlab】绘图插入并放大/缩小子图

参考链接 代码分为两个:绘图代码与magnify.m 绘图代码就是普通的绘图代码,以下为例 %https://zhuanlan.zhihu.com/p/655767542 clc clear close all x 0:pi/100:2*pi; y1 sin(x); plot(x,y1,r-o); hold on y2sin(x)-0.05; y3sin(x)0.05; xlim([0 2*…

C#关键字概览

C#是一种面向对象的编程语言,由微软开发并作为.NET框架的一部分。它具有丰富的关键字,用于定义程序的结构和行为。本文将详细介绍C#中的关键字,包括基本关键字、上下文关键字以及它们在C#编程中的使用方式。 访问修饰符 访问修饰符控制成员…

Python变量age:深入探索其内涵与运用

Python变量age:深入探索其内涵与运用 在Python的世界里,变量age不仅是一个简单的标识符,它更是一个承载着丰富信息和功能的实体。今天,我们就来深入探索这个看似简单的age变量,揭示其背后的奥秘和魅力。 四个方面&am…

供应SKYA21001思佳讯芯片现货

长期供应各进口品牌芯片现货: SKYA21001 QM11024TR13 QM12113TR13 QM42391 QM45392 QM28005 RF8020TR13 QM77033DTR13 QM56021TR13-5K 885171 QM77043 QM78207 QM77038TR13 SKY58081-11 QPF5752QTR13-5K RF7198TR13-5K SKY58255-11 SKY85720-11 …

Ubuntu中安装和配置SSH的完全指南

目录 前言 第1步:安装SSH服务器 第2步:检查防火墙设置 第3步:连接到SSH服务器 第4步:配置SSH服务器(可选) 更改SSH端口 禁用root登录 第5步:公钥认证(建议) 结论…

XSS Challenges 闯关游戏环境准备:深入指南

在网络安全领域,理解并掌握跨站脚本攻击(XSS)的防御技巧至关重要。为了帮助学习者深入实践XSS攻击与防御,“XSS Challenges” 闯关游戏提供了一个实操平台。本文将详细介绍如何准备这一环境。 1. 环境准备概述 XSS Challenges 闯…

Kubernetes 之 Secret

Kubernetes 之 Secret Secret 的定义 Secret 解决了密码、token、秘钥等敏感数据的配置问题,它避免了把这些敏感数据直接暴露在镜像或者 Pod 的配置文件中。但是它只是一种相对安全的策略,我们还是可以在容器内找到这些信息。 Secret 的认证方式 认证…

eclipse-向Console控制台输出信息

首先这里主要用到的是org.eclipse.ui.console这个包,所以现在顺道先来了解一下: org.eclipse.ui.console是一个可扩展的console视图插件,利用它可以实现各种console,并把它们显示出来。该插件本身就实现了一个Message Console&…

本地 Java API 访问云上 HDFS 集群的问题与解决

前言 这篇文章默认是已经在云上配置好了 Haoop 集群,因此本文主要是记录一些可能会出现错误的地方。 如果还不会配置 Hadoop 集群,那么可以参考本专栏的另一篇文章:云上配置 Hadoop 集群详解 另外在进行本文的学习之前也建议先看看该文章&…