二叉树(一)

news2024/11/16 18:37:47

先简单了解一下树的概念,从而进一步了解二叉树,最后进行代码测试。

树概念及结构(了解)

在认识而二叉树之前我们首先了解一下树的概念。

树是一种非线性的数据结构,它是由n(n>=0)个有限结点组成一个具有层次关系的集合。把它

叫做树是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。

我们与之前学过的 顺序表、单链表、双链表、栈和队列,都是线性结构,及必须访问了前一个或者后一个才能访问目标节点,而我们今天了解的数据结构(树)是非线性结构,可以跳过部分节点直接访问目标节点。

树:顾名思义长得像现实生活的树(倒着的)。

数据结构(树)

节点的度:一个节点含有的子树的个数称为该节点的度; 如上图:A的为6

叶节点或终端节点:度为0的节点称为叶节点; 如上图:B、C、H、I...等节点为叶节点

非终端节点或分支节点:度不为0的节点; 如上图:D、E、F、G...等节点为分支节点

注意:我们如果把A看成’1‘层的话,那么‘ 0 ’层表示没有树;如果把A用数组的下标表示的化就是’0‘,哪儿买没有树就是’-1‘(这个表达有点怪)。

双亲节点或父节点:若一个节点含有子节点,则这个节点称为其子节点的父节点; 如上图:A是B

的父节点

孩子节点或子节点:一个节点含有的子树的根节点称为该节点的子节点; 如上图:B是A的孩子节

兄弟节点:具有相同父节点的节点互称为兄弟节点; 如上图:B、C是兄弟节点

这里其实我们可以用我们现实生活中的复杂的亲戚关系作类比。

树的度:一棵树中,最大的节点的度称为树的度; 如上图:树的度为6

节点的层次:从根开始定义起,根为第1层,根的子节点为第2层,以此类推;

树的高度或深度:树中节点的最大层次; 如上图:树的高度为4

节点的祖先:从根到该节点所经分支上的所有节点;如上图:A是所有节点的祖先

子孙:以某节点为根的子树中任一节点都称为该节点的子孙。如上图:所有节点都是A的子孙

森林:由m(m>0)棵互不相交的多颗树的集合称为森林;(数据结构中的学习并查集本质就是

一个森林)

树的表示

我们发现如果我们把它设置成一个静态的,就不能够实现。

我们假设树有许多孩子。那么我们可以尝试把代码写成这样:

typedef int DataType;
struct Node
{
    struct Node* _firstChild1; // 第一个孩子结点
    struct Node* _firstChild2; // 第二个孩子结点
    struct Node* _firstChild3; // 第三个孩子结点

    //...

    DataType _data;
};

我们发现这样是不行的。这里其实我们如过运用c++里的知识,可以想象一下,我们如果可以自由的开辟空间,那么有再多的‘孩子’其实也无所谓。

struct TreeNode
{
    int data;
    vector<struct TreeNode*> childs;
};

但是我们的目的是打算用C语言实现,我们能不能用“左孩子右兄弟”的方式来解决呢?

typedef int DataType;
struct Node
{
struct Node* _firstChild1; // 第一个孩子结点
struct Node* _pNextBrother; // 指向其下一个兄弟结点
DataType _data; // 结点中的数据域
};

“左孩子右兄弟”的实现原理

其实通过存“父亲的下标”也能够实现。(其实并查集就是用的方法,一般树不用该方法)

树的应用

我们常用的文件夹结构就是这样:

文件夹(Linux)

二叉树的组成部分

  1. 根节点

  1. 左子树

  1. 右子树

分 治 算 法 : 分 而 治 之 , 大 问 题 分 成 类 似 子 问 题 , 子 问 题 再 分 成 子 问 题 .

直 到 子 问 题 不 可 再 分 割

我们对数的概念有所了解以后再来了解二叉树。

二叉树

前序顺序

原理:根节点,左子树和右子树。

顺序:A B D NULL NULL NULL C E NULL NULL F NULL NULL

这里有个窍门,就是把一侧全部数完,再来数另一侧的,跟递归一样。

中序顺序

原理:左子树,根节点和右子树。

一样的图。依照我们之前学的套路。

顺序就是:NULL D NULL B NULL A NULL E NULL C NULL F NULL

那么知道后序顺序的原理——左子树,右子树和根节点。我们写出后序顺序应该不难,大家可以自己尝试一下,有问题欢迎大家评论区讨论。

测试

我们讲了这么多。我们用代码简单实现一下前序顺序。

按照我们之前讲的套路,初始化就是这样。

typedef char BTDateType;

typedef struct BinaryTree
{
    struct BinaryTree* left;
    struct BinaryTree* right;
    BTDateType data;
}BTDnode;

那么访问就是这样实现。

//访问
void PreOrder(BTDnode* root)
{
    if (root == NULL)
    {
        printf("NULL ");
        return;
    }
    printf("%c ", root->data);
    PreOrder(root->left);
    PreOrder(root->right);
}

当然如果大家想实现中序的话就是这样的。

//访问
void PreOrder(BTDnode* root)
{
    if (root == NULL)
    {
        printf("NULL ");
        return;
    }
    PreOrder(root->right);
    //中序就是先走左边
    printf("%c ", root->data);
    PreOrder(root->left);
}

这里其实我们可以用我们之前学的单链表直接调用,但是这样有点繁琐,我们完全可以自己做一个静态简易版链表。

int main()
{
    //链表

    BTDnode* A = (BTDnode*)malloc(sizeof(BTDnode));
    A->data = 'A';
    A->left = NULL;
    A->right= NULL;

    BTDnode* B = (BTDnode*)malloc(sizeof(BTDnode));
    B->data = 'B';
    B->left = NULL;
    B->right = NULL;

    BTDnode* C = (BTDnode*)malloc(sizeof(BTDnode));
    C->data = 'C';
    C->left = NULL;
    C->right = NULL;

    BTDnode* D = (BTDnode*)malloc(sizeof(BTDnode));
    D->data = 'D';
    D->left = NULL;
    D->right = NULL;

    BTDnode* E= (BTDnode*)malloc(sizeof(BTDnode));
    E->data = 'E';
    E->left = NULL;
    E->right = NULL;

    return 0;
}

然后我们再来链接在一块就是了。

int main()
{
    BTDnode* A = (BTDnode*)malloc(sizeof(BTDnode));
    A->data = 'A';
    A->left = NULL;
    A->right= NULL;

    BTDnode* B = (BTDnode*)malloc(sizeof(BTDnode));
    B->data = 'B';
    B->left = NULL;
    B->right = NULL;

    BTDnode* C = (BTDnode*)malloc(sizeof(BTDnode));
    C->data = 'C';
    C->left = NULL;
    C->right = NULL;

    BTDnode* D = (BTDnode*)malloc(sizeof(BTDnode));
    D->data = 'D';
    D->left = NULL;
    D->right = NULL;

    BTDnode* E= (BTDnode*)malloc(sizeof(BTDnode));
    E->data = 'E';
    E->left = NULL;
    E->right = NULL;

    A->left = B;
    A->right = C;

    B->left = D;
    B->right = E;

    PreOrder(A);
    printf("\n");

    return 0;
}

但是有些同学递归学的有点迷糊,就难以理解是如何实现的。这里我再来画一幅图。

我们接下来再来画一下递归图。

递归原理(左图)

其实画完比较复杂的左图,相对简单的右图完全可以想象出来,各位小伙伴可以自己动手试一下。

总结

我们一起探讨了,数的结构和概念,从而引出本节重点——二叉树,简单了解完其概念和原理以后,我们就对其做了测试,为了进一步理解二叉树的原理,我再用递归的方式对二叉树做了原理图,我们发现递归的原理图和二叉树长得很像。

下一节我们将进一步学习二叉树的原理。

欢迎大家的评论和点赞!

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

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

相关文章

图扑喜获第十一届中国创新创业大赛全国赛优秀奖!

在近期结束的第十一届中国创新创业大赛全国赛&#xff08;新一代信息技术&#xff09;比赛中&#xff0c;图扑软件喜获成长组优秀奖。这是继“创客中国”创新创业大赛优胜奖荣誉后&#xff0c;再一次对图扑软件在新一代信息技术领域专业的认可&#xff01;大赛围绕新一代信息技…

电机行业EDI案例分析

项目背景 J公司需要与国内某知名电机品牌Z公司建立EDI对接&#xff0c;J公司选择通过知行EDI系统与Z公司建立AS2连接&#xff0c;通过AS2接收Z公司发送过来的ORDERS&#xff08;采购订单&#xff09;和ORDCHG&#xff08;采购订单变更&#xff09;&#xff0c;并根据发接收到的…

Linux常见命令 15 - 权限管理命令 chmod

1. chmod 语法 chmod为修改文件/文件夹权限&#xff0c;有以下两种操作&#xff0c;其中-R表示递归修改 chmod {ugoa} {-} {rwx} [文件或目录] -Rchmod [mode421] [文件或目录] -R 2. chmod {ugoa} {-} {rwx} [文件或目录] -R u&#xff1a;文件或目录的所有者&#xff0c;g…

C++设计模式(5)——观察者模式

观察者模式 亦称&#xff1a; 事件订阅者、监听者、Event-Subscriber、Listener、Observer 意图 观察者模式是一种行为设计模式&#xff0c; 允许你定义一种订阅机制&#xff0c; 可在对象事件发生时通知多个 “观察” 该对象的其他对象。 问题 假如你有两种类型的对象&a…

概论第6章_正态总体的抽样分布_卡方分布_F分布_t分布

一 卡方分布 定义 设X1,X2,...,XnX_1, X_2,..., X_nX1​,X2​,...,Xn​ 独立同分布于标准正态分布N(0, 1), 则χ2X12...Xn2\chi^2X_1^2 ... X_n^2χ2X12​...Xn2​的分布称为 自由度为 n 的χ2\chi^2χ2分布&#xff0c; 记为χ2\chi^2χ2 ~ χ2(n)\chi^2(n)χ2(n) χ2\chi…

Python爬虫序章---爬取csdn作者排行榜

上篇文章介绍了requests库获取数据的基本方法&#xff0c;本篇文章利用自动化测试工具selenium进行数据抓取&#xff0c;也会对代码部分进行详细解释&#xff0c;以便小伙伴们能够更加理解和上手。 一.selenium技术介绍 Selenium是最广泛使用的开源 Web UI&#xff08;用户界面…

windows11远程连接Ubuntu桌面

如何通过Windows 11远程连接Ubuntu桌面 在日常开发过程中&#xff0c;很多时候是这样一种情形&#xff1a;一台装了Ubuntu系统的计算机作为远程服务器&#xff0c;开发人员则使用带Windows系统的计算机去连服务器进行开发。 连接服务器的方式有很多种&#xff0c;最简单的就是…

图扑软件荣获第十一届中国创新创业大赛全国赛优秀奖!

在近期结束的第十一届中国创新创业大赛全国赛&#xff08;新一代信息技术&#xff09;比赛中&#xff0c;图扑软件喜获成长组优秀奖。这是继“创客中国”创新创业大赛优胜奖荣誉后&#xff0c;再一次对图扑软件在新一代信息技术领域专业的认可&#xff01;大赛围绕新一代信息技…

DW动手学数据分析Task4:数据可视化

目录1 了解matplotlib2 可视化图案3 matplotlib用法4 了解Seaborn1 了解matplotlib Matplotlib&#xff1a; 是 Python 的绘图库&#xff0c; 它可与 NumPy 一起使用&#xff0c;提供了一种有效的 MatLab 开源替代方案。 2 可视化图案 基本可视化团及场景使用 柱状图 场景&am…

如何实现机械臂的正解计算?

1. 机械臂运动学介绍 机械臂运动学 机器人运动学就是根据末端执行器与所选参考坐标系之间的几何关系&#xff0c;确定末端执行器的空间位置和姿态与各关节变量之间的数学关系。包括正运动学&#xff08;Forward Kinematics&#xff09;和逆运动学&#xff08;Inverse Kinematic…

在线支付系列【3】支付安全之对称和非对称加密

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 文章目录前言信息安全加密机制核心概念对称加密非对称加密JCE对称加解密1. 创建密钥2. 加密3. 解密非对称加解密1. 创建密钥2. 公钥加密3. 私钥解密前言 支付和金钱挂钩&#xff0c;支付安全显得尤为重…

域名被封的解决方案

如果您的域名被封&#xff0c;可能是域名下网站存在非法信息或敏感内容&#xff0c;导致被GFW屏蔽。 封禁原因及解决方案如下&#xff1a; 1. 域名解析的IP纳入黑名单 这种情况只需更换IP即可恢复正常&#xff0c;但换IP也只能解除一时的燃眉之急&#xff0c;一旦又被GFW发现很…

MySQL进阶——视图(view)

1. 视图 1.1 视图介绍 视图&#xff08;View&#xff09;是一种虚拟存在的表。视图中的数据并不在数据库中实际存在&#xff0c;行和列数据来自定义视图的查询中使用的表&#xff0c;并且是在使用视图时动态生成的。 通俗的讲&#xff0c;视图只保存了查询的SQL逻辑&#xf…

MySQL详细教程,2023年硬核学习路线

文章目录前言1. 数据库的相关概念1.1 数据1.2 数据库1.3 数据库管理系统1.4 数据库系统1.5 SQL2. MySQL数据库2.1 MySQL安装2.2 MySQL配置2.2.1 添加环境变量2.2.2 新建配置文件2.2.3 初始化MySQL2.2.4 注册MySQL服务2.2.5 启动MySQL服务2.3 MySQL登录和退出2.4 MySQL卸载2.5 M…

【Python】如何为Matplotlib图像添加标签?

一、添加文本标签 plt.text() 用于在绘图过程中&#xff0c;在图像上指定坐标的位置添加文本。需要用到的是plt.text()方法。 其主要的参数有三个&#xff1a; plt.text(x, y, s)其中x、y表示传入点的x和y轴坐标。s表示字符串。 需要注意的是&#xff0c;这里的坐标&#x…

基于Springboot+Mybatis+mysql+vue电影院在线售票系统

基于SpringbootMybatismysqlvue电影院在线售票系统一、系统介绍二、所用技术三、功能展示1.主页(普通用户)2.影院管理员相关功能&#xff08;影院管理员&#xff09;3.系统管理权限(管理员)四、获取源码一、系统介绍 电影院网上售票系统拥有三种角色&#xff0c;用户、工作人员…

三星K2200复印机提示更换传输卷问题的简单处理

故障现象: 三星K2200复印机开机后提示更换传输卷; 故障分析与处理: 三星K2200复印机提示更换传输卷是转印带使用寿命到期,三星k2200复印件更换传输卷,是指转印带使用寿命到期了,需要更换传输卷。如果这台机器报传输卷一般是这台机器也有一条转印带,如果报这个看看上面…

C/C++数据结构(十一)—— 平衡二叉树(AVL树)

文章目录1. AVL树的概念2. AVL树的结点3. AVL树的插入&#x1f351; 更新平衡因子&#x1f351; 插入函数的实现4. AVL树的旋转&#x1f351; 左单旋&#x1f351; 右单旋&#x1f351; 左右双旋&#x1f351; 右左双旋&#x1f351; 总结6. AVL树的删除&#x1f351; 算法思想…

基于EasyExcel实现百万级数据导入导出

基于EasyExcel实现百万级数据导入导出 在项目开发中往往需要使用到数据的导入和导出&#xff0c;导入就是从Excel中导入到DB中,而导出就是从DB中查询数据然后使用POI写到Excel上。 大数据的导入和导出&#xff0c;相信大家在日常的开发、面试中都会遇到。 很多问题只要这一次…

2022-12-08版本:Open Inventor Toolkit SDK Crack

为什么使用 Open Inventor Toolkit Open Inventor SDK 是一种商业 3D 软件开发工具包 ( SDK )&#xff0c;适用于医疗和牙科、石油和天然气、工程领域的专业应用。 Open Inventor其面向对象的 API、可扩展的架构及其大量高级组件为软件开发人员提供了一个高级平台&#xff0c;…