初阶数据结构:二叉树

news2024/11/26 10:22:30

目录

  • 1. 树的相关概念
    • 1.1 简述:树
    • 1.2 树的概念补充
  • 2. 二叉树
    • 2.1 二叉树的概念
    • 2.2 二叉树的性质
    • 2.3 二叉树的存储结构与堆
      • 2.3.1 存储结构
      • 2.3.2 堆的概念
      • 2.3.3 堆的实现
        • 2.3.3.1 堆的向上调整法
        • 2.3.3.2 堆的向下调整算法
        • 2.3.3.3 堆的实现

1. 树的相关概念

1.1 简述:树

树是一种非线性的数据结构,其有n个有限的节点构成,树结构具有层次性。它的形状颇像一颗颠倒的树,因此而被称为树。

补充:

  1. 树的结构中有一个特殊的结点,其没有前驱结点,被称为根结点。
  2. 树的结构中,其子树间不能存在交集,若存在交集,那么,此结构就不能被称为树结构。

1.2 树的概念补充

在这里插入图片描述

  1. 节点的度:一个节点含有的子树的个数称为该节点的度;(A结点的度为3)
  2. 叶子节点:度为0的结点;(E, F, G, D, H结点)
  3. 非叶子节点:度不为0的结点(B,C, G结点)
  4. 父亲节点:若一个节点含有子节点,则这个节点称为其子节点的父节点
  5. 子节点:一个节点含有的子树的根节点称为该节点的子节点;
  6. 兄弟节点:具有相同父节点的节点互称为兄弟节点;
  7. 树的度:一棵树中,最大的节点的度称为树的度;
  8. 节点的层 :从根开始定义起,根为第1层,根的子节点为第2层,以此类推;
  9. 树的深度 :树中节点的最大层次;
  10. 堂兄弟结点 :双亲在同一层的节点互为堂兄弟;
  11. 祖先结点:从根到该节点所经分支上的所有节点;
  12. 子孙结点 :以某节点为根的子树中任一节点都称为该节点的子孙;
  13. 森林: 多棵互不相交的树的集合

2. 二叉树

2.1 二叉树的概念

对于树结构的初次学习,我们来重点学习二叉树这一结构。

在这里插入图片描述

由上图可知,二叉树具有两个特点:

  1. 二叉树是一个结点的集合,可能为空或者由根节点,左子树,右子树构成。
  2. 二叉树由左右子树之分,所以,二叉树为一个有序树,其顺序不能颠倒。
  3. 二叉树的没有拥有超过两个孩子结点的结点,即二叉树的度为2
  4. 补充:特殊的二叉树
    <1> 满二叉树:除叶子结点外,所有结点都有左右孩子结点,若k二叉树的层数,那么满二叉树的结点就有 k 2 k^2 k2 - 1个结点。
    <2> 完全二叉树:除最后一层外,所有结点都有左右孩子结点,最后一层叶子结点连续

在这里插入图片描述

2.2 二叉树的性质

  1. 若规定根节点的层数为1,则一棵非空二叉树的第i层上最多有2^(i - 1) 个结点.
  2. 若规定根节点的层数为1,则深度为h的二叉树的最大结点数是 2 h 2^h 2h - 1.(等比数列求和)
  3. 任何一棵二叉树, 如果度为0其叶结点个数为n, 则其度为0的结点一定比度为2的结点多一个.
  4. 若规定根节点的层数为1,具有n个结点的满二叉树的深度,h = l o g 2 ( n + 1 ) log_2(n + 1) log2(n+1)
  5. 对于具有n个结点的完全二叉树,如果按照从上至下从左至右的数组顺序对所有节点从0开始编号,则对于序号为i的结点有:
    <1> 若i>0,i位置节点的双亲序号:(i-1)/2;i=0,i为根节点编号,无双亲节点
    <2> 若2i+1<n,左孩子序号:2i+1,2i+1>=n否则无左孩子
    <3> 若2i+2<n,右孩子序号:2i+2,2i+2>=n否则无右孩子

2.3 二叉树的存储结构与堆

2.3.1 存储结构

  1. 顺序存储:
    其采用的方式为使用数组进行数据的存储,其各个结点的关系通过下标之间的数学关系来实现,在物理结构上其仍为数组,此结构只适合存储完全二叉树。
  2. 链式存储:
    使用链表的方式来存储数据,其存在三个域,数据域,左孩子指针域,右孩子指针域。在逻辑上,呈现链式的逻辑结构。

2.3.2 堆的概念

  1. 堆是一棵完全二叉树。
  2. 堆分为大堆与小堆,当所有结点的值都大于孩子结点时即为大堆,当所有结点的值都小于其孩子结点时即为小堆。

2.3.3 堆的实现

  1. 因为堆都是完全二叉树,这里我们使用顺序存储的方式来进行堆的实现。
  2. 在数组中若父亲节点的下标为pos,其左孩子的下标为pos × 2 + 1,右孩子结点的下标为pos × 2 + 2,下标为0的元素为根结点。(顺序存储方式,使用数组来实现堆结构的方式)

在这里插入图片描述

我们已经知晓了如何判断一个数组是否为堆,可我们对下面两个问题还是没有办法去解决:

  1. 当一个数组是堆时,我们如何保证在不断向数组中插入数据而堆的结构不被打乱。
  2. 如何将一个不是堆的数组调整为堆。
  3. 如何去创建一个是堆的数组。

我们接下来进行这几个问题的学习。

2.3.3.1 堆的向上调整法

在这里插入图片描述

void HeapAdjustUp(int* arr, int child)
{
	int parent = (child - 1) / 2;

	while (child > 0)
	{
		if (arr[parent] < arr[child])
		{
			swap(&arr[parent], &arr[child]);
			child = parent;
			parent = (child - 1) / 2;
		}
		else
		{
			break;
		}
	}
}

向上调整建堆

  1. 将数组中的元素从首元素开始一个一个视作插入已有的堆中在进行向上调整,初始堆为空。

那么,我们就可以进行如下操作:

for(int i = 0; i < n; i++)
{
	HeapAdjustUp(arr, i);
}
2.3.3.2 堆的向下调整算法
void HeapAdjustDown(int* arr, int n, int parent)
{
	//n为元素个数
	int child = parent * 2 + 1;

	while (child < n)
	{
		if (child + 1 < n && arr[child] < arr[child + 1])
		{
			child++;
		}

		if (arr[parent] < arr[child])
		{
			swap(&arr[parent], &arr[child]);
			parent = child;
			child = parent * 2 + 1;
		}
		else
		{
			break;
		}
	}
}

向下调整法建堆
2. 我们从最后一个非叶子结点开始,向下调整,调整过后的子树都为堆,一直循环到根结点。

操作如下:

过程演示:
在这里插入图片描述

for (int j = (n - 1 - 1) / 2; j >= 0; j--)
{
	HeapAdjustDown(arr, n, j);
}
2.3.3.3 堆的实现

堆的结构:

typedef struct Heap
{
	int* data;
	int size;
	int capacity;
}Heap;

堆的初始化与销毁:

void HeapInit(Heap* heap)
{
	heap->data = NULL;
	heap->capacity = heap->size = 0;
}

void HeapDestroy(Heap* heap)
{
	while (heap->size)
	{
		HeapPop(heap);
	}

	free(heap->data);
	heap->data = NULL;
	heap->capacity = heap->size = 0;
}

堆的元素增加与头删

void CheckCapacity(Heap* heap)
{
	if (heap->size == heap->capacity)
	{
		int newcapacity = heap->capacity == 0 ? 4 : heap->capacity * 2;
		int* tmp = (int*)realloc(heap->data, newcapacity * sizeof(int));
		if (tmp == NULL)
		{
			perror("malloc failed");
			exit(-1);
		}

		heap->data = tmp;
		heap->capacity = newcapacity;
	}
}

void HeapPush(Heap* heap, int val)
{
	CheckCapacity(heap);

	heap->data[heap->size] = val;
	heap->size++;

	HeapAdjustUp(heap->data, heap->size - 1);
}

//逆置首尾元素,size--,再向下调整
//向下调整后堆仍为堆的前置条件为,左右子树都为堆
void HeapPop(Heap* heap)
{
	assert(!HeapEmpty(heap));

	swap(&heap->data[0], &heap->data[heap->size - 1]);
	heap->size--;
	//左右子树都为堆
	HeapAdjustDown(heap->data, heap->size, 0);
}

返回堆顶元素与判空:

bool HeapEmpty(Heap* heap)
{
	return heap->size == 0;
}

int HeapTop(Heap* heap)
{
	assert(!HeapEmpty(heap));

	return heap->data[0];
}

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

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

相关文章

Java多线程——信号量Semaphore是啥

目录 引出信号量Semaphore &#xff1f;Redis冲冲冲——缓存三兄弟&#xff1a;缓存击穿、穿透、雪崩缓存击穿缓存穿透缓存雪崩 总结 引出 Java多线程——信号量Semaphore是啥 信号量Semaphore &#xff1f; Semaphore 通常我们叫它信号量&#xff0c; 可以用来控制同时访问特…

Day36 网络概述、IP划分、网络模型

文章目录 网络发展史局域网和广域网局域网&#xff08;LAN&#xff09;广域网&#xff08;Wan&#xff09; 光猫路由器 IP地址基本概念地址划分特殊地址&#xff08;后续编程使用&#xff09;IP地址转换端口字节序 网络模型网络模型OSI模型&#xff08;了解&#xff09;TCP/IP模…

15:Zookeeper高可用集群|分布式消息队列Kafka|搭建高可用Hadoop集群

Zookeeper高可用集群&#xff5c;分布式消息队列Kafka&#xff5c;搭建高可用Hadoop集群 Zookeeper集群Zookeeper角色与特性Zookeeper角色与选举Zookeeper的高可用Zookeeper可伸缩扩展性原理与设计Zookeeper安装zookeeper集群管理 Kafka概述在node节点上搭建3台kafka 高可用Had…

Vue.js+SpringBoot开发高校学院网站

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 学院院系模块2.2 竞赛报名模块2.3 教育教学模块2.4 招生就业模块2.5 实时信息模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 学院院系表3.2.2 竞赛报名表3.2.3 教育教学表3.2.4 招生就业表3.2.5 实时信息表 四、系…

循环队列--C语音实现

目录 一、循环队列的特点&#xff1a; 二、普通的队列的缺点&#xff1a; 三、循环队列实现原理&#xff1a; 四、循环队列是实现步骤&#xff1a; 1.循环队列的头文件&#xff1a; 2.循环队列的源文件&#xff1a; 3.注意点&#xff1a; 一、循环队列的特点&#xff1…

灯塔:CSS笔记(1)

CSS&#xff1a;层叠样式表 所谓层叠 即叠加的意思&#xff0c;表示样式可以一层一层的层叠覆盖 css写在style标签中&#xff0c;style标签一般写在head标签里面&#xff0c;title标签下面 <!DOCTYPE html> <html lang"en"> <head><meta cha…

java 从环境变量中获取参数及值

window直接在这设置&#xff1a; linux在/etc/profile文件里存放&#xff1a; export keyvalue 然后立即生效&#xff1a;source /etc/profile 代码获取值这样获取&#xff1a; System.getenv("key");

C++初阶篇----类与对象中卷

目录 引言1. 构造函数1.1概念1.2 特性 2. 析构函数2.1 概念2.2 特性 3. 拷贝构造函数3.1 概念3.2特征 4. 赋值运算符重载4.1 运算符重载4.2 赋值运算符重载4.3 前置和后置重载 5.日期类的实现6.const成员7.取地址及const取地址操作符重载 引言 当一个类既没有成员变量又没有成…

【特征选择】CMA-ES(协方差矩阵适应进化策略)

导 读 当将模型拟合到数据集时&#xff0c;可能需要执行特征选择&#xff1a;由于多种原因&#xff0c;仅保留某些特征子集来拟合模型&#xff0c;而丢弃其余特征具有一定的必要性&#xff0c;如下&#xff1a; 保持模型的可解释性&#xff08;特征太多会使解释变得更加困难&am…

css-解决Flex布局下居中溢出滚动截断问题

css-解决Flex布局下居中溢出滚动截断问题 1.出现的问题2.解决方法2.1 Flex 布局下关键字 safe、unsafe2.2 使用 margin: auto 替代 justify-content: center2.3 额外嵌套一层 1.出现的问题 在页面布局中&#xff0c;我们经常会遇到/使用列表内容水平居中于容器中&#xff0c;一…

Codesys自定义库的帮助文档的美化

文章目录 1.前言2.美化的方式2.1.利用html标签2.2.利用reStructuredText 3.相关说明3.1.使用reStructuredText时&#xff0c;中文注释的问题3.2.将文档需要的图片包含到库中3.3.文档的作用区域 1.前言 当我们在codesys中写好自己的库&#xff0c;并且发布给别人使用时&#xf…

overleaf latex 笔记

overleaf: www.overleaf.com 导入.tex文件 1.代码空一行&#xff0c;代表文字另起一段 2. 1 2 3 排序 \begin{enumerate} \item \item \item \end{enumerate} 3.插入图片 上传图片并命名 \usepackage{float}导包\begin{figure}[H]&#xff1a;表示将图…

大数据最佳实践

本文主要收录一些大数据不错的实践文章 1、数禾云上数据湖最佳实践 https://blog.51cto.com/u_15089766/2601706 该文章介绍了数禾云的数据胡实践&#xff0c;包含presto以及数据湖等组件的一些部署架构&#xff0c;文章听不错的&#xff0c;里面提到了为了避免presto与yarn计…

汽车中网上的logo不能改,需要到车管所备案

需要备案。 车辆改装需到车辆管理所办理登记。 机动车每年检验时&#xff0c;需要对外观进行检测。 中国在线的标志不能更改。 汽车格栅是汽车前部进气口附近相关部件的总称。 汽车的中网主要位于水箱、发动机、空调等设备的前面&#xff0c;控制进气和通风&#xff0c;防止行…

3d怎么拖模型---模大狮模型网

在3D建模软件中拖动(移动)模型通常是一种基本的操作&#xff0c;用来调整模型的位置或布局。以下是一般情况下在3D建模软件中拖动模型的基本步骤&#xff1a; 3d拖模型的步骤&#xff1a; 选择模型&#xff1a;在3D建模软件中选中你要拖动的模型。通常可以通过单击模型来选中它…

#define MODIFY_REG(REG, CLEARMASK, SETMASK)

#define MODIFY_REG(REG, CLEARMASK, SETMASK) WRITE_REG((REG), (((READ_REG(REG)) & (~(CLEARMASK))) | (SETMASK))) 这个宏 MODIFY_REG 是在嵌入式编程中&#xff0c;它用于修改一个寄存器的特定位&#xff0c;而不影响其他位。这个宏接受三个参数&#xff…

无代理方式实现VMware的迁移?详细解析

在当今数字化时代&#xff0c;数据的安全性和可用性对于企业至关重要。尤其是在VMware转变订阅策略后&#xff0c;原本永久订阅的产品转变为以年付费订阅的形式&#xff0c;导致客户不得不支付更多的费用&#xff0c;大幅增加了成本。同时&#xff0c;客户也对VMware未来发展前…

鹅厂打工8年,我为啥突然裸辞?

公众号&#xff1a;程序员白特&#xff0c;欢迎一起交流学习~ 原文&#xff1a;以下文章来源于沐洒 &#xff0c;作者ASCII26 今天跟大家分享一个重磅消息&#xff0c;沐洒终于从腾讯离职了&#xff01; 不知不觉已经在鹅厂打了8年工&#xff0c;如果说在大厂里工作如同在高校…

DAY 12滑动串口最大值【单调队列】 前K个高频元素【优先级队列】

6.滑动窗口最大值 队列的应用&#xff01;&#xff01; 给你一个整数数组 nums&#xff0c;有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。 返回 滑动窗口中的最大值 。 示例 1&#xff…

deep image matting

[Matting]论文阅读&#xff1a;Deep Image Matting 详细解读-CSDN博客文章浏览阅读3.5k次&#xff0c;点赞2次&#xff0c;收藏10次。[Matting]论文阅读&#xff1a;Deep Image Matting 详细解读一 、摘要二、方法2.1 第一部分&#xff08;Matting encoder-decoder stage&#…