初级数据结构(五)——树和二叉树的概念

news2024/11/15 14:01:36

    文中代码源文件已上传:数据结构源码

 <-上一篇 初级数据结构(四)——队列        |        NULL 下一篇->

1、树结构(Tree)

1.1、树结构的特点

        自然界中的树由根部开始向上生长,随机长出分支,分支之上又可长出分支,层层递进,直至长出叶子则此分支结束。

        数据结构中“树”的概念便是借鉴大自然中的树,将下图垂直镜像翻转便是如此,只是在画结构图时往往更习惯由上向下画。它从根节点开始不断长出分支,直至终端。与自然中的树不同点在于,随着数据后续插入,树结构的叶子节点也可能变为分支节点。

        尤其需要注意,不同分支上的节点不可互相交织。下图中红色线条连接到其他分支的节点,这就不属于树结构:

        总之,树是若干个节点的有限集,有且仅有一个根节点。树的分支数量可以任意多,也可以不包含分支仅有一个根节点甚至没有节点(没有节点的树称为空树)。不同分支的节点互不相交。

1.2、常用名词

         在了解树结构特点的同时,为了后续使用该结构时方便描述,还应了解几个名词。

        节点( Node ):树中的每一个元素称为节点,上图中每个圆圈都代表一个节点;

        根节点( Root ):最初的节点称为根节点,如上图中的 A ;

        子树( Subtree ):每个节点除开自身,将下一级节点当作新的根节点,从新的根节点往下所有节点的集合称为该节点的子树。上图中 B 及往后的节点是 A 的子树, F 又是 B 的子树(所以树是递归结构);

        分支节点( Branch ):能够延申出其他节点的节点(度不为 0 的节点)都称作分支节点,如上图中红色及蓝色标识的节点都属于分支节点;

        终端节点、叶子节点( Leaf ):不包含任何分支节点的节点(度为 0 的节点)称为终端节点或者叶子节点。上图中绿色标识的节点属于叶子节点;

        度( Degree ):一个节点的分支数量叫作该节点的度,如上图 E 有两个分支 K 和 L ,所以 E 的度是 2 。一棵树中所有节点的度的最大值就是这棵树的度,上图中度最大的节点是 J , 有 4 个度,所以这棵树的度也是 4 ;

        层次( Level ):从树或者子树的顶层到最底层的顺序进行排序。在这个顺序中,每个节点都被视为位于树的某个层次上。最顶上可以视为第 0 层,也可以视作第 1 层。

        深度、高度(Depth):最大层次称为这棵树的深度或者高度。如图中的树从根节点开始向下,最多可经 A、D、J、O、S 这 5 个节点( 5 个层次),所以这棵树的深度为 5 ;

        父节点、双亲节点( Parent ):一个节点的上一级节点称为该节点的父节点或者双亲节点。如图中 E 是 K 的父节点,A 是 B 的父节点;

        子节点( Child ):一个节点的下一级节点称为该节点的子节点。图中的 O、P、Q、R 都是 J 的子节点;

        兄弟节点( Sibling ):与某个节点有同一个父节点的节点称为兄弟节点。如图 E、F 都是 G 的兄弟节点;

        祖先节点( Ancestry ):某个节点上数若干级直到根节点,经过的这些节点都称为祖先节点。图中 A、C、H 都是 M 或者 N 的祖先节点;
        子孙节点( Descendant ):一个节点往下的所有节点都称为该节点的子孙节点。如图中 I、J、O、P、Q、R、S 都是 D 的子孙节点;

        堂兄弟节点( Cousin ):与某个节点同一层次除了自身和兄弟节点外其他所有节点称为该节点的堂兄弟节点。如图中 H、I、J 都是 E、F、G 的堂兄弟节点;

        森林( Forest ):若干颗互不相交的树称为森林。图中剔除 A 节点后, B、C、D 子树则构成森林;

        有序树( Ordered Tree ):一棵树中各子树按照一定规律排序不可互换,则称为有序树。如图中如果将这棵树的 A、B、C …… 当作一种顺序,那么可视为有序树;

        无序树( Unordered Tree ):有序树之外的树都称作无序树。

1.3、树的存储方式

        如上图的树结构,如果要在代码中定义其结构体,常规能想到的是除了定义一个储存数据的成员变量外,定义若干个子节点指针。而由于子节点的数量是不确定的,因此将其定义为数组。

typedef int DATATYPE;
typedef struct Node
{
    DATATYPE data;            //存储数据
    size_t childCount;        //子节点个数
    size_t capacity;          //已开辟空间大小
    struct Node* child[0];    //子节点指针数组
}Node;

        若要找到图中 1-2-2 节点则执行:

root->child[0]->child[1]->child[1];

        但这对于有序树这种不可随意交换节点位置的结构还好,如果是无序树,而且在经常需要交换节点的情况下, 频繁挪动数组元素显得十分不灵活。因此,还有一种储存方式,每个节点仅储存第一个子节点和其下一个兄弟节点的指针。

        在结构体创建上也显得简单,而且无需每次添加数据都检查空间:

typedef int DATATYPE;
typedef struct Node
{
    DATATYPE data;
    struct Node* sibling;
    struct Node* child;
}Node;

        同样是找到 1-2-2 节点:

root->child->child->sibling->child->sibling;

        看似更为复杂,但整个结构在增删数据或者交换数据的操作上跟之前的结构完全不是一个量级。具体过程这里就不展开赘述,实际上就是对链表和顺序表在增删数据或者交换数据操作上的区别。

2、二叉树( Binary Tree )

2.1、节点基本形态

        二叉树是一种特殊的树,每个节点的子节点不超过 2 个,它的度最大为 2  。此外,二叉树是有序树。一般其节点的结构体类型如下:

typedef int DATATYPE;
typedef struct Node
{
    DATATYPE data;
    struct Node* left;
    struct Node* right;
}

        因此,二叉树包含以下五种基本形态: 

        其中,由于二叉树是有序树,所以左分支形态和右分支形态不是同一种结构,代码的表现上也完全不同:

//空
root = NULL;
//无分支
root->left = NULL;
root->right = NULL;
//左分支
root->left = &nodeLeft;
root->right = NULL;
//右分支
root->left = NULL;
root->right = &nodeRight;
//双分支
root->left = &nodeLeft;
root->right = &nodeRight;

2.2、二叉树的特殊形态

2.2.1、斜二叉树

        所有节点的左或者右节点全为空的二叉树称为斜二叉树。斜二叉树每一层有且只有一个节点,节点数等于树的深度。如图。

        斜二叉树可看作是一种非环状单链表,使用上也与单链表无差异。

2.2.2、完全二叉树

        如果二叉树的深度为 n ,根节点处于第 0 层,除了最底层节点,其余每一层中第 L 层节点个数 C_{L} 都满足 C_{L} = 2^{L} ,且底层最右侧节点满足其父节点的左子节点不为空,其堂兄弟节点的父节点度都为 2 ,则这类二叉树称为完全二叉树。如下图。

        上面的描述可能有点过于抽象,可以观察图片,然后用另一种方式概括:

                a、完全二叉树的叶子节点仅存在该二叉树的最底层和次底层;

                b、最底层的叶子节点无空隙地紧密排列在左边部分,右边部分可以为空;

                c、次底层的叶子节点无空隙地紧密排列在这一层右侧;

                d、次底层节点的度为 1 时,该节点没有右子节点。

         在同样节点数的二叉树中,不存在其他形态的二叉树深度小于完全二叉树。

2.2.3、满二叉树

        满二叉树是一种特殊的完全二叉树,如图。

        满二叉树的叶子节点只能出现在最下层,每个非叶子节点的分支节点度都为 2 。在所有同深度的二叉树中,满二叉树的节点最多。

2.3、二叉树规律

2.3.1、节点数规律

        二叉树的叶子节点数量总是比度为 2 的节点数多 1 个。

        根据上图可知,叶子节点数量增加总是伴随着度为 2 的节点数增加,而起初只有根节点时,叶子节点数为 1 ,度为 2 的节点数为 0 。因此无论如何增加节点,叶子节点数总是比度为 2 的节点数多 1 个。

2.3.2、完全二叉树标号规律

        将完全二叉树节点如下图编号:

        会发现完全二叉树左子节点编号是其 2 倍,右子节点编号是其 2 倍 +1 (重要性质,下一篇关于堆的内容会用到)。

2.3.3、完全二叉树深度

        已知完全二叉树节点数为 n ,其深度为 (int)log_{2}n+1 。

        根据以下代码可以计算出完全二叉树的深度:

#include <math.h>
#include <stdio.h>

int main()
{
    int nodeCount;
    scanf("%d", &nodeCount);
    int depth = (int)(log(nodeCount) / log(2)) + 1;
    printf("Depth = %d\n", depth);
    return 0;
}

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

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

相关文章

在Node.js中MongoDB查询分页的方法

本文主要介绍在Node.js中MongoDB查询分页的方法。 目录 Node.js中MongoDB查询分页使用原生的mongodb驱动程序查询分页使用Mongoose库进行查询分页注意项 Node.js中MongoDB查询分页 在Node.js中使用MongoDB进行查询分页&#xff0c;可以使用原生的mongodb驱动程序或者Mongoose库…

AtCoder ABC周赛2023 12/10 (Sun) D题题解

目录 原题截图&#xff1a; 题目大意&#xff1a; 主要思路&#xff1a; 注&#xff1a; 代码&#xff1a; 原题截图&#xff1a; 题目大意&#xff1a; 给定两个 的矩阵 和 。 你每次可以交换矩阵 的相邻两行中的所有元素或是交换两列中的所有元素。 请问要使 变换至…

LLaMA的解读与其微调:Alpaca-LoRA/Vicuna/BELLE/中文LLaMA/姜子牙/LLaMA 2

前言 近期&#xff0c;除了研究ChatGPT背后的各种技术细节 不断看论文(至少100篇&#xff0c;100篇目录见此&#xff1a;ChatGPT相关技术必读论文100篇)&#xff0c;还开始研究一系列开源模型(包括各自对应的模型架构、训练方法、训练数据、本地私有化部署、硬件配置要求、微调…

Ubuntu22.04添加用户

一、查看已存在的用户 cat /etc/passwd 二、添加用户 sudo adduser xxx 除了密码是必须的&#xff0c;其他的都可以不填&#xff0c;直接回车即可 三、查看添加的用户 cat /etc/passwd 四、将新用户添加到sudo组 sudo adduser xxx sudo 五、删除用户 sudo delus…

H5ke15--1--文本管理器拖进来

1如图1&#xff0c;父元素没有行高&#xff0c;子元素就不继承&#xff0c;有了就变成图2 2或者直接写表格自动垂直居中&#xff0c;但是table太古老了&#xff0c;没人用这个&#xff0c;如图3 3我们父元素display: table;展示位表格&#xff0c;子元素display: table-cell;…

HTML + JavaScript 实现网页录制音频与下载

HTML JavaScript 实现网页录制音频与下载 HTML JavaScript 实现网页录制音频与下载简介getUserMediaMediaRecorder获取和处理音频流实现音频的录制和播放音频效果的处理实时语音通话的应用兼容性和 Latency 问题 项目代码运行实例参考源码下载 HTML JavaScript 实现网页录制…

WEB渗透—PHP反序列化(三)

Web渗透—PHP反序列化 课程学习分享&#xff08;课程非本人制作&#xff0c;仅提供学习分享&#xff09; 靶场下载地址&#xff1a;GitHub - mcc0624/php_ser_Class: php反序列化靶场课程&#xff0c;基于课程制作的靶场 课程地址&#xff1a;PHP反序列化漏洞学习_哔哩…

dockerfile创建镜像 lNMP+wordpress

dockerfile创建镜像 lNMPwordpress nginx dockernginx mysql dockermysql php dockerphp nginx vim nginx.conf vim Dockerfile docker network create --subnet172.17.0.0/16 --opt "com.docker.network.bridge.name""docker1" mynetwork docker buil…

Redis设计与实现之对象处理机制

目录 一、前言 二、对象处理机制 1、redisObject 数据结构&#xff0c;以及 Redis 的数据类型 2、 命令的类型检查和多态 3、对象共享 4、引用计数以及对象的销毁 三、对象的处理 1、Redis是如何处理字符串对象的&#xff1f; 2、Redis是如何处理列表对象的&#xff1f…

Arduino中以太网Udp通信

目录 1、测试硬件 2、程序 &#xff08;0&#xff09;头文件添加 &#xff08;1&#xff09;变量定义 &#xff08;2&#xff09;初始化程序 &#xff08;3&#xff09;循环执行程序 3、程序下载 &#xff08;1&#xff09;开发板控制器和端口号选择 &#xff08;2&am…

java基础知识④:设计模式

目录 一、设计模式 1️⃣创建型设计模式&#xff08;常用&#xff1a;单例、工厂、抽象工厂&#xff09; 2️⃣结构型设计模式&#xff08;常用&#xff1a;适配器、装饰者、外观、代理&#xff09; 3️⃣行为型设计模式&#xff08;常用&#xff1a;观察者、策略、模板方法、命…

windows下redis 设置开机自启动

1&#xff0c;在redis的目录下执行&#xff08;执行后就作为windows服务了&#xff09; redis-server --service-install redis.windows.conf 2&#xff0c;安装好后需要手动启动redis redis-server --service-start 3&#xff0c;停止服务 redis-server --service-stop

springMVC 学习总结(四) 拦截器及统一异常处理

一.拦截器 1.拦截器与过滤器的区别 拦截器 Interceptor 和 过滤器 Filter类似&#xff0c;主要用于拦截用户请求并作出一定处理操作&#xff0c; 但两则也有不同之处&#xff0c;如过滤器只在Servlet前后起作用&#xff0c;是Servlet规范定义的&#xff0c;是Servlt容器才支…

邮政快递查询,邮政快递单号查询,根据更新量筛选出需要的单号

批量查询邮政快递单号的物流信息&#xff0c;并根据物流更新量将需要的单号筛选出来。 所需工具&#xff1a; 一个【快递批量查询高手】软件 邮政快递单号若干 操作步骤&#xff1a; 步骤1&#xff1a;运行【快递批量查询高手】软件&#xff0c;第一次使用的伙伴记得先注册&…

stm32H库的内部FLASH读写操作与结构体数组数据写入与读取

stm32H库的内部FLASH读写操作与结构体数组数据写入与读取 1.软硬件准备2.关于STM32的Flash的一些说明3.实验结果 参考博主-STM32系列(HAL库)——内部FLASH读写实验 1.软硬件准备 软件&#xff1a;CubeMX、SSCOM&#xff08;串口调试助手&#xff09; 硬件&#xff1a;SMT32F…

SQL进阶理论篇(七):B+树的查询及存储机制

文章目录 简介数据库中的存储结构数据库中的页结构从数据页来看B树的查询过程总结参考文献 简介 我们之前已经了解过数据库的B树索引和Hash索引&#xff0c;这些索引信息以及数据记录都是保存在文件里的&#xff0c;确切的说是存储在页结构中。 本节&#xff0c;从我们将了解…

Agilent安捷伦34972A数据采集仪34908A采集卡

附加功能: 3插槽LXI数据采集单元&#xff0c;带6位数字数字多用表(22位)和8个插件模块可供选择(单独出售) 测量11种不同的输入信号(无外部信号调理)&#xff0c;包括热电偶、RTD和热敏电阻的温度&#xff1b;DC/交流伏特或电流&#xff1b;2线或4线电阻&#xff1b;频率和周期…

FindMy技术用于滑雪板

随着冬季运动的日益普及&#xff0c;滑雪板作为滑雪运动的重要器材&#xff0c;也变得越来越受欢迎。在各大雪场和户外运动场所&#xff0c;人们纷纷挥舞着滑雪板&#xff0c;畅享冬季运动的乐趣。 在滑雪过程中&#xff0c;由于雪场的复杂环境和运动的高速性&#xff0c;很容易…

数据结构之排序

目录 ​ 1.常见的排序算法 2.插入排序 直接插入排序 希尔排序 3.交换排序 冒泡排序 快速排序 hoare版本 挖坑法 前后指针法 非递归实现 4.选择排序 直接选择排序 堆排序 5.归并排序 6.排序总结 一起去&#xff0c;更远的远方 1.常见的排序算法 排序&#xff1a;所…

Linux学习笔记-Ubuntu下ssh服务器连接异常Connection reset

文章目录 一、问题问题现象1.1 连接重置无法访问的的问题1.2 查看服务器连接状态1.3 使用调试模式查看的信息 二、临时解决方法三、从根源解决问题3.1 问题分析3.2 服务器的ssh日志3.3 修改ssh配置禁止root登录3.4 配置允许所有ip访问3.5 修改认证方法 角色&#xff1a;百世经纶…