【数据结构】树与二叉树(五):二叉树的顺序存储(初始化,插入结点,获取父节点、左右子节点等)

5.1 树的基本概念

5.1.1 树的定义

  • 一棵树是结点的有限集合T:
    • 若T非空,则:
      • 有一个特别标出的结点,称作该树的,记为root(T);
      • 其余结点分成若干个不相交的非空集合T1, T2, …, Tm (m>0),其中T1, T2, …, Tm又都是树,称作root(T)的子树
    • T 空时为空树,记作root(T)=NULL。

5.1.2 森林的定义

  一个森林是0棵或多棵不相交(非空)树的集合,通常是一个有序的集合。换句话说,森林由多个树组成,这些树之间没有交集,且可以按照一定的次序排列。在森林中,每棵树都是独立的,具有根节点和子树,树与树之间没有直接的连接关系。
  森林是树的扩展概念,它是由多个树组成的集合。在计算机科学中,森林也被广泛应用于数据结构和算法设计中,特别是在图论和网络分析等领域。
在这里插入图片描述

5.1.3 树的术语

  • 父亲(parent)、儿子(child)、兄弟(sibling)、后裔(descendant)、祖先(ancestor)
  • 度(degree)、叶子节点(leaf node)、分支节点(internal node)
  • 结点的层数
  • 路径、路径长度、结点的深度、树的深度

参照前文:【数据结构】树与二叉树(一):树(森林)的基本概念:父亲、儿子、兄弟、后裔、祖先、度、叶子结点、分支结点、结点的层数、路径、路径长度、结点的深度、树的深度

5.1.4 树的表示

  • 【数据结构】树与二叉树(二):树的表示C语言:树形表示法、嵌套集合表示法、嵌套括号表示法 、凹入表示法

5.2 二叉树

5.2.1 二叉树

1. 定义

  二叉树是一种常见的树状数据结构,它由结点的有限集合组成。一个二叉树要么是空集,被称为空二叉树,要么由一个根结点和两棵不相交的子树组成,分别称为左子树右子树。每个结点最多有两个子结点,分别称为左子结点和右子结点。
在这里插入图片描述

2. 特点

  二叉树的特点是每个结点最多有两个子结点,并且子结点的位置是有序的,即左子结点在前,右子结点在后。这种有序性使得二叉树在搜索、排序等算法中有广泛的应用。

  • 在二叉树中,根结点是整个树的起始点,通过根结点可以访问到整个树的其他结点。每个结点都可以看作是一个独立的二叉树,它的左子树和右子树也是二叉树。

  • 二叉树可以是空树,也可以是只有根结点的树,或者是由多个结点组成的树。每个结点可以包含一个数据元素,以及指向左子结点和右子结点的指针。

  • 二叉树的形状可以各不相同,它可以是平衡的或者不平衡的,具体取决于结点的分布情况。在二叉树中,每个结点的左子树和右子树都是二叉树,因此可以通过递归的方式来处理二叉树的操作。

3. 性质

引理5.1:二叉树中层数为i的结点至多有 2 i 2^i 2i个,其中 i ≥ 0 i \geq 0 i0
引理5.2:高度为k的二叉树中至多有 2 k + 1 − 1 2^{k+1}-1 2k+11个结点,其中 k ≥ 0 k \geq 0 k0
引理5.3:设T是由n个结点构成的二叉树,其中叶结点个数为 n 0 n_0 n0,度数为2的结点个数为 n 2 n_2 n2,则有 n 0 = n 2 + 1 n_0 = n_2 + 1 n0=n2+1
  • 详细证明过程见前文:【数据结构】树与二叉树(三):二叉树的定义、特点、性质及相关证明

4. 满二叉树

在这里插入图片描述

  定义5.3:一棵非空高度为 k ( k ≥ 0 ) k( k≥0) k(k0)满二叉树(perfect binary tree),是有 2 k + 1 − 1 2^{k+1}-1 2k+11个结点的二叉树。

5. 完全二叉树

  定义5.4:一棵包含 n n n个节点、高度为 k k k的二叉树 T T T,当按层次顺序编号 T T T的所有节点,对应于一棵高度为 k k k的满二叉树中编号由1至 n n n的那些节点时, T T T被称为完全二叉树(complete binary tree)

  • 满二叉树、完全二叉树性质及证明:【数据结构】树与二叉树(四):满二叉树、完全二叉树及其性质

5.2.2 二叉树顺序存储

  二叉树的顺序存储是指将二叉树中所有结点按层次顺序存放在一块地址连续的存储空间中
  对于完全二叉树,结点的层次顺序反映了其结构,可按层次顺序给出一棵完全二叉树之结点的编号,事实上,这就是完全二叉树的顺序存储方法,结点编号恰好反映了结点间的逻辑关系。
  只要对完全二叉树之结点按照层次顺序进行编号,就可利用一维数组 A A A来存储一棵含有 n n n个结点的完全二叉树,其中A[1]存储二叉树的根结点,A[i]存储二叉树中编号为i的结点,并且结点A[i]的左儿子(若存在)存放在A[2i]处,而A[i]的右儿子(若存在)存放在A[2i+1]处。注意,这里我们约定数组索引从1开始,而不是从0开始,在使用数组存储完全二叉树时,需要留出A[0]位置不使用。

典例

在这里插入图片描述

  首先,我们按照完全二叉树的结点顺序进行编号,从上到下、从左到右依次编号。根据给出的完全二叉树,我们可以得到以下结点编号:

         1/ \2   3/ \4   5

  接下来,我们可以利用一维数组来存储这棵完全二叉树。创建一个大小为6的数组A,其中A[1]表示根结点 A A AA[2]表示结点 B B BA[3]表示结点 E E EA[4]表示结点 C C CA[5]表示结点 D D D

索引:  1   2   3   4   5
数组: [ A,  B,  E,  C,  D ]

  根据完全二叉树的性质,结点 A A A的左儿子应该存放在A[2]的位置,右儿子应该存放在A[3]的位置。结点 B B B的左儿子应该存放在A[4]的位置,右儿子应该存放在A[5]的位置。

例题

  画出下面这棵完全二叉树的顺序存储结构:
在这里插入图片描述
答案见文末 答案见文末 答案见文末

  完全二叉树的顺序存储方式是一种简单且节省空间的存储方式。它只需要使用一个一维数组来存储完全二叉树的结点信息域的值,而不需要额外的空间来存储左儿子和右儿子的地址。

  通过计算结点的编号和数组索引之间的关系,我们可以方便地找到结点的左儿子、右儿子和父亲结点。例如,对于结点i,它的左儿子的编号是2i,右儿子的编号是2i+1,父亲结点的编号是⌊i/2⌋。这种计算关系使得寻找子孙结点和祖先结点变得非常方便和高效。

  顺序存储方式的优点是节省了存储空间,同时访问结点也非常快速,因为可以通过数组索引直接访问结点,而不需要进行指针的跳转。然而,顺序存储方式也有一些限制。由于使用数组存储,需要提前确定完全二叉树的最大结点个数,因此对于结点数不确定或者动态变化的情况下,顺序存储方式可能不适用。

C语言实现

  注意,这里我们约定数组索引从0开始,节点位置计算公式与前文略有不同。

#include <stdio.h>
#include <stdlib.h>#define MAX_SIZE 100  // 定义数组的最大大小// 二叉树的顺序存储结构
typedef struct {char data[MAX_SIZE];  // 数组用于存储结点的数据int size;  // 二叉树的大小(结点个数)
} BinaryTree;// 初始化二叉树
void initBinaryTree(BinaryTree* tree) {tree->size = 0;
}// 向二叉树中插入结点
void insertNode(BinaryTree* tree, int value, int index) {if (tree->size >= MAX_SIZE) {printf("Binary tree is full. Cannot insert more nodes.\n");return;}if (index < 0 || index > tree->size) {printf("Invalid index.\n");return;}// 将插入位置后的结点后移for (int i = tree->size - 1; i >= index; i--) {tree->data[i + 1] = tree->data[i];}// 插入新结点tree->data[index] = value;tree->size++;
}// 获取结点的父节点编号
int getParentIndex(int index) {return (index - 1) / 2;
}// 获取结点的左子节点编号
int getLeftChildIndex(int index) {return 2 * index + 1;
}// 获取结点的右子节点编号
int getRightChildIndex(int index) {return 2 * index + 2;
}// 根据索引获取结点的值
char getNodeValue(BinaryTree* tree, int index) {if (index >= tree->size || index < 0) {printf("Invalid index.\n");return -1;}return tree->data[index];
}int main() {BinaryTree tree;initBinaryTree(&tree);// 向二叉树中插入结点insertNode(&tree, 'A', 0);  insertNode(&tree, 'B', 1);  insertNode(&tree, 'E', 2); insertNode(&tree, 'C', 3); insertNode(&tree, 'D', 4); // 获取结点的值和子节点的值char rootValue = getNodeValue(&tree, 0);char leftChildValue = getNodeValue(&tree, getLeftChildIndex(0));char rightChildValue = getNodeValue(&tree, getRightChildIndex(0));printf("Root value: %c\n", rootValue);printf("Left child of Root: %c\n", leftChildValue);printf("Right child of Root: %c\n", rightChildValue);printf("the Parent of B: %c\n", getNodeValue(&tree, getParentIndex(1)));printf("the Parent of C: %c\n", getNodeValue(&tree, getParentIndex(3)));printf("the Parent of D: %c\n", getNodeValue(&tree, getParentIndex(4)));printf("the Parent of E: %c\n", getNodeValue(&tree, getParentIndex(2)));return 0;
}

在这里插入图片描述

答案

在这里插入图片描述
在这里插入图片描述

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

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

相关文章

Flink(一)【WordCount 快速入门】

前言 学完了 Hadoop、Spark&#xff0c;本想着先把 Kafka、Flume 这些工具先学完的&#xff0c;但想了想还是把核心的技术先学完最后再去把那些工具学学。 最近心有点累哈哈哈&#xff0c;偷偷立个 flag&#xff0c;反正也没人看&#xff0c;明年的今天来这里还愿哈&#xff0c…

基于Java Web的在线教学质量评价系统的设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…

机器学习——回归

目录 一、线性回归 1、回归的概念&#xff08;Regression、Prediction&#xff09; 2、符号约定 3、算法流程 4、最小二乘法&#xff08;LSM&#xff09; 二、梯度下降 梯度下降的三种形式 1、批量梯度下降&#xff08;Batch Gradient Descent,BGD&#xff09;&#xff…

MES系统防呆措施之具体场景学习

在工业设计上&#xff0c;为了避免使用者的操作失误造成机器或人身伤害&#xff08;包括无意识的动作或下意识的误动作或不小心的肢体动作&#xff09;&#xff0c;会针对这些可能发生的情况来做预防措施&#xff0c;称为防呆。对于注塑生产企业来讲&#xff0c;模具亦是企业的…

MinGW32丢失dll文件

问题现象 执行Makefile的时候&#xff0c;突然出现这个提示&#xff0c;还有好几个类似的&#xff0c;提示我找不到dll文件&#xff0c;建议重装。 问题分析 重装软件 最直接的办法肯定是按照建议来重装&#xff0c;但是发现重装了好几次&#xff0c;不是缺这个就是缺那个&a…

Linux多线程【线程池】

✨个人主页&#xff1a; 北 海 &#x1f389;所属专栏&#xff1a; Linux学习之旅 &#x1f383;操作环境&#xff1a; CentOS 7.6 腾讯云远程服务器 文章目录 &#x1f307;前言&#x1f3d9;️正文1.线程池的概念1.1.池化技术1.2.线程池的优点1.3.线程池的应用场景 2.线程池的…

Vue路由使用参数传递数据

一、使用query参数传递数据 &#xff08;一&#xff09;参数的传递 1. 携带参数进行传递 <router-link to"/路径?参数名1参数值1&参数名2参数值2">内容</router-link> 我们在下面的代码中传递每条消息的id和标题&#xff1a; 2. 配置对象进行传递…

运动想象 EEG 信号分析

基于运动想象的公开数据集&#xff1a;Data set IVa (BCI Competition III)1 数据描述参考前文&#xff1a;https://blog.csdn.net/qq_43811536/article/details/134224005?spm1001.2014.3001.5501 本文使用公开数据集 Data set IVa 中的部分被试数据&#xff0c;数据已公开可…

C#在.NET Windows窗体应用中使用LINQtoSQL

目录 一、新建Windows窗体应用并添加LINQtoSQL类 二、错误信息CS0234 三、添加扩展包让Windows窗体应用支持LINQtoSQL类 默认安装的背景下&#xff0c;新建的Windows窗体应用是不支持LINQtoSQL类的。现象是资源管理器里的依赖项中默认的安装不能自动生成支持system.data.lin…

如何在Python爬虫中使用IP代理以避免反爬虫机制

目录 前言 一、IP代理的使用 1. 什么是IP代理&#xff1f; 2. 如何获取IP代理&#xff1f; 3. 如何使用IP代理&#xff1f; 4. 如何避免IP代理失效&#xff1f; 5. 代理IP的匿名性 二、代码示例 总结 前言 在进行爬虫时&#xff0c;我们很容易会遇到反爬虫机制。网站…

JS操作字符串常见方法

目录 一&#xff1a;前言 二&#xff1a;常见的内置方法 1、charAt与charCodeAt 2、indexOf与lastIndexOf 3、substring与substr 4、toLowerCase 和 toUpperCase 5、slice 6、replace 7、split 8、concat 9、trim 10、trimStart / trimLeft 11、trimEnd / trimRigh…

flutter开发报错The instance member ‘widget‘ can‘t be accessed in an initializer

文章目录 问题描述问题原因解决方法 问题描述 The instance member ‘widget’ can’t be accessed in an initializer. 问题原因 “The instance member ‘widget’ can’t be accessed in an initializer” 错误是因为在初始化器列表中&#xff08;constructor initializer…

[ACTF2020 新生赛]Upload 1

题目环境&#xff1a; 仍旧是文件上传漏洞 这道题和上一道大差不差、大同小异、这里不再赘述。 [极客大挑战 2019]Upload 1&#xff1a;https://blog.csdn.net/m0_73734159/article/details/134267317?spm1001.2014.3001.5501 区别在于本题需要在抓包数据里面改文件后缀&#…

2023年11月5日网规考试备忘

早上题目回忆&#xff1a; pki体系 ipsec&#xff0c;交换安全&#xff08;流量抑制&#xff09; aohdlc bob metclaf —ethernet pon tcp三次握手 OSPF lsa&#xff1f;交换机组ospf配置问题&#xff0c;ping网关可通&#xff0c;AB不通 raid6 300G*8 网络利用率 停等协议10…

《009.Springboot+vue之进销存管理系统》

《009.Springbootvue之进销存管理系统》 项目简介 [1]本系统涉及到的技术主要如下&#xff1a; 推荐环境配置&#xff1a;DEA jdk1.8 Maven MySQL 前后端分离; 后台&#xff1a;SpringBootMybatisredis; 前台&#xff1a;vueElementUI; [2]功能模块展示&#xff1a; 1.用户管…

亚马逊合规,亚马逊涉及12个站点合规政策更新,需警惕合规要求!

最近&#xff0c;许多亚马逊站点的卖家陆续收到了合规政策更新的通知邮件&#xff0c;涵盖了美国站、加拿大站、英国站、法国站、意大利站、德国站以及西班牙站。 这些更新影响了不同品类的卖家&#xff0c;包括以下品类&#xff1a; 美国站&#xff08;US&#xff09;对于“发…

【Linux】:文件系统

文件系统 一.认识硬件-磁盘1.磁盘的物理构成2.磁盘的存储构成3.逻辑结构 二.文件系统 文件内容属性&#xff0c;前面我们所说的文件操作都是针对以打开的文件&#xff0c;那么未打开的文件呢&#xff1f;当然是在磁盘上储存着&#xff0c;接下来谈谈它是如何储存的。 一.认识硬…

JavaEE平台技术——MyBatis

JavaEE平台技术——MyBatis 1. 对象关系映射框架——Hibernate、MyBatis2. 对象关系模型映射3. MyBatis的实现机制4. MyBatis的XML定义5. Spring事务 在观看这个之前&#xff0c;大家请查阅前序内容。 &#x1f600;JavaEE的渊源 &#x1f600;&#x1f600;JavaEE平台技术——…

个性化联邦学习-综述

介绍阅读的三篇个性化联邦学习的经典综述文章 Three Approaches for Personalization with Applications to Federated Learning 论文地址 文章的主要内容 介绍了用户聚类&#xff0c;数据插值&#xff0c;模型插值三种个性化联邦学习的方法。 用户聚类&#xff1a; 目的&a…

智能井盖传感器助力建设数字化城市

在推进智慧城市建设过程中&#xff0c;多个城市在打造数字化管理平台&#xff0c;因为通过科学技术手段统一管理城市各种基础设施建设&#xff0c;可以缓解传统人工不足所导致的执法困难的问题&#xff0c;而且可以方便城市管理及时响应。在智慧城市建设过程中&#xff0c;城市…