初阶数据结构:二叉树

目录

  • 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];
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

链表基础知识详解(非常详细简单易懂)

概述&#xff1a; 链表作为 C 语言中一种基础的数据结构&#xff0c;在平时写程序的时候用的并不多&#xff0c;但在操作系统里面使用的非常多。不管是RTOS还是Linux等使用非常广泛&#xff0c;所以必须要搞懂链表&#xff0c;链表分为单向链表和双向链表&#xff0c;单向链表很…

[Linux]如何理解kernel、shell、bash

文章目录 概念总览kernelshell&bash 概念总览 内核(kernel) &#xff0c;外壳(shell) &#xff0c;bash kernel kernel是指操作系统中的核心部分&#xff0c;用户一般是不能直接使用kernel的。它主要负责管理硬件资源和提供系统服务&#xff0c;如内存管理、进程管理、文件…

国内chatgpt写作软件,chatgpt国内使用

随着人工智能技术的不断发展&#xff0c;国内涌现出了一些基于ChatGPT模型的写作软件&#xff0c;这些软件不仅能够实现智能化的文章写作&#xff0c;还支持批量生成各种类型的文章。本文将深入探讨国内ChatGPT写作软件&#xff0c;以及它们在批量文章创作方面的应用与优势。 C…

如何使用Docker搭建StackEdit编辑器并结合内网穿透实现远程办公

文章目录 前言1. ubuntu安装VNC2. 设置vnc开机启动3. windows 安装VNC viewer连接工具4. 内网穿透4.1 安装cpolar【支持使用一键脚本命令安装】4.2 创建隧道映射4.3 测试公网远程访问 5. 配置固定TCP地址5.1 保留一个固定的公网TCP端口地址5.2 配置固定公网TCP端口地址5.3 测试…

K线实战分析系列之十七:三法形态——接连犹豫后再次坚定

K线实战分析系列之十七&#xff1a;三法形态——接连犹豫后再次坚定 一、三法形态二、总结三法形态 一、三法形态 前后两根长K线中间夹了三根短小的K线 二、总结三法形态 中间的几根小阴线数量限制没有那么严苛中间小K线的颜色不一定是依次下降的小阴线或小阳线&#xff0c;也…

NOC2023软件创意编程(学而思赛道)python小高组复赛真题

目录 下载原文档打印做题: 软件创意编程 一、参赛范围 1.参赛组别:小学低年级组(1-3 年级)、小学高年级组(4-6 年级)、初中组。 2.参赛人数:1 人。 3.指导教师:1 人(可空缺)。 4.每人限参加 1 个赛项。 组别确定:以地方教育行政主管部门(教委、教育厅、教育局) 认…

【C++】vector的使用和模拟实现(超级详解!!!!)

文章目录 前言1.vector的介绍及使用1.1 vector的介绍1.2 vector的使用1.2.1 vector的定义1.2.2 vector iterator 的使用1.2.3 vector 空间增长问题1.2.3 vector 增删查改1.2.4 vector 迭代器失效问题。&#xff08;重点!!!!!!&#xff09;1.2.5 vector 在OJ中有关的练习题 2.ve…

朱维群将出席用碳不排碳碳中和顶层科技路线设计开发

演讲嘉宾&#xff1a;朱维群 演讲题目&#xff1a;“用碳不排碳”碳中和顶层科技路线设计开发 简介 姓名&#xff1a;朱维群 性别&#xff1a;男 出生日期&#xff1a;1961-09-09 职称&#xff1a;教授 1998年毕业于大连理工大学精细化工国家重点实验室精细化工专业&…

AWTK 开源串口屏开发(11) - 天气预报

# AWTK 开源串口屏开发 - 天气预报 天气预报是一个很常用的功能&#xff0c;在很多设备上都有这个功能。实现天气预报的功能&#xff0c;不能说很难但是也绝不简单&#xff0c;首先需要从网上获取数据&#xff0c;再解析数据&#xff0c;最后更新到界面上。 在 AWTK 串口屏中…

探索那些能唤起情感共鸣的壁纸

1、方小童在线工具集 网址&#xff1a; 方小童 该网站是一款在线工具集合的网站&#xff0c;目前包含PDF文件在线转换、随机生成美女图片、精美壁纸、电子书搜索等功能&#xff0c;喜欢的可以赶紧去试试&#xff01;

基于Beego 1.12.3的简单website实现

参考 用Beego开发web应用 https://www.cnblogs.com/zhangweizhong/p/10919672.htmlBeego官网 Homepage - beego: simple & powerful Go app frameworkbuild-web-application-with-golang https://github.com/astaxie/build-web-application-with-golang/blob/master/zh/pr…

概率基础——多元正态分布

概率基础——多元正态分布 介绍 多元正态分布是统计学中一种重要的多维概率分布&#xff0c;描述了多个随机变量的联合分布。在多元正态分布中&#xff0c;每个随机变量都服从正态分布&#xff0c;且不同随机变量之间可能存在相关性。本文将以二元标准正态分布为例&#xff0…

PVLAN组网实验

一&#xff0c;PVLAN类型 主VLAN 主VLAN可以由多个辅助私用VLAN组成&#xff0c;而这些辅VLAN与主VLAN属于同一子网。 辅助VLAN ① 团体VLAN&#xff1a;如果某个端口属于团体VLAN&#xff0c;那么它就不仅能够与相同团体VLAN中的其他端口进行通信&#xff0c;而且还能够与…

【5G 接口协议】GTP-U协议介绍

博主未授权任何人或组织机构转载博主任何原创文章&#xff0c;感谢各位对原创的支持&#xff01; 博主链接 本人就职于国际知名终端厂商&#xff0c;负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作&#xff0c;目前牵头6G算力网络技术标准研究。 博客…

HTML~

HTML HTML是一门语言&#xff0c;所有的网页都是用HTML这门语言编写出来的HTML(HyperText Markup Language):超文本标记语言 超文本:超越了文本的限制&#xff0c;比普通文本更强大。除了文字信息&#xff0c;还可以定义图片、音频、视频等内容 标记语言:由标签构成的语言 …

SpringBoot源码解读与原理分析(三十八)SpringBoot整合WebFlux(一)WebFlux的自动装配

文章目录 前言第13章 SpringBoot整合WebFlux13.1 响应式编程与Reactor13.1.1 命令式与响应式13.1.2 异步非阻塞13.1.3 观察者模式13.1.4 响应性13.1.5 响应式流13.1.6 背压13.1.7 Reactor13.1.7.1 Publisher13.1.7.2 Subscriber13.1.7.3 Subscription13.1.7.4 Processor13.1.7.…

Python爬虫——解析常用三大方式之Xpath

目录 Xpath 安装xpath 安装lxml库 导入lxml库 解析本地文件 etree.parse&#xff08;&#xff09; 解析服务器响应文件 etree.HTML() xpath基本语法 小案例&#xff1a;获取百度首页的百度一下 大案例&#xff1a;爬取站长素材图片 总结 Xpath 安装xpath 首先要学会安…

大模型(LLM)的量化技术Quantization原理学习

在自然语言处理领域&#xff0c;大型语言模型&#xff08;LLM&#xff09;在自然语言处理领域的应用越来越广泛。然而&#xff0c;随着模型规模的增大&#xff0c;计算和存储资源的需求也急剧增加。为了降低计算和存储开销&#xff0c;同时保持模型的性能&#xff0c;LLM大模型…

【排序算法】冒泡排序

目录 概述 冒泡排序原理 冒泡排序的Java实现 总结 概述 冒泡排序是一种简单但低效的排序算法。它重复地走访要排序的元素列&#xff0c;一次比较两个元素&#xff0c;如果它们的顺序错误就交换它们&#xff0c;直到没有元素需要交换。这个过程类似于气泡在水中上浮的过程&am…

开源模型Mistral 7B+Amazon SageMaker部署指南

一、Mistral 7B简述 Mistral AI 是一家总部位于法国的 AI 公司&#xff0c;其使命是将公开可用的模型提升至最先进的性能水平。他们专注于构建快速而安全的大型语言模型&#xff08;LLM&#xff09;&#xff0c;此类模型可用于从聊天机器人到代码生成等各种任务。不久前其发布…