数据结构-二叉树_堆

数据结构-二叉树_堆

目录

1.二叉树的概念

​编辑1.1树的概念与结构

1.2树的相关语

1.3 树的表示

2. ⼆叉树

2.1 概念与结构

2.2 特殊的⼆叉树

2.2.2 完全⼆叉树

2.3 ⼆叉树存储结构

2.3.1 顺序结构

2.3.2 链式结构

3. 实现顺序结构⼆叉树

3.2 堆的实现

 3.2.2 向下调整算法


1.二叉树的概念

1.1树的概念与结构

二叉树和上面的图片一样,有一个根,然后生出两个枝,一个枝又长出两个枝,并且每个枝最多长出两个枝。

  • 有一个特殊的节点,叫做根节点,他没有前驱节点
  • 除根结点外,其余结点被分成 M(M>0) 个互不相交的集合 T1、T2、……、Tm ,其中每⼀个集合 Ti(1 <= i <= m) ⼜是⼀棵结构与树类似的⼦树。每棵⼦树的根结点有且只有⼀个前驱,可以 有 0 个或多个后继。因此,树是递归定义的。

子树之间是不能有交集的

1.2树的相关语

  • ⽗结点/双亲结点:若⼀个结点含有⼦结点,则这个结点称为其⼦结点的⽗结点; 如上图:A是B的⽗ 结点
  • ⼦结点/孩⼦结点:⼀个结点含有的⼦树的根结点称为该结点的⼦结点; 如上图:B是A的孩⼦结点
  • 结点的度:⼀个结点有⼏个孩⼦,他的度就是多少;⽐如A的度为6,F的度为2,K的度为0 树的度:⼀棵树中,最⼤的结点的度称为树的度; 如上图:树的度为 6
  • 叶⼦结点/终端结点:度为 0 的结点称为叶结点; 如上图: B、C、H、I... 等结点为叶结点 分⽀结点/⾮终端结点:度不为 0 的结点; 如上图: D、E、F、G... 等结点为分⽀结点
  • 兄弟结点:具有相同⽗结点的结点互称为兄弟结点(亲兄弟); 如上图: B、C 是兄弟结点 比特就业课
  • 结点的层次:从根开始定义起,根为第 1 层,根的⼦结点为第 2 层,以此类推;
  • 树的⾼度或深度:树中结点的最⼤层次; 如上图:树的⾼度为 4
  • 结点的祖先:从根到该结点所经分⽀上的所有结点;如上图: A 是所有结点的祖先
  • 路径:⼀条从树中任意节点出发,沿⽗节点-⼦节点连接,达到任意节点的序列;⽐如A到Q的路径为: A-E-J-Q;H到Q的路径H-D-A-E-J-Q
  • ⼦孙:以某结点为根的⼦树中任⼀结点都称为该结点的⼦孙。如上图:所有结点都是A的⼦孙
  • 森林:由 m(m>0) 棵互不相交的树的集合称为森林;

1.3 树的表示

孩⼦兄弟表⽰法: 树结构相对线性表就⽐较复杂了,要存储表⽰起来就⽐较⿇烦了,既然保存值域,也要保存结点和结 点之间的关系,实际中树有很多种表⽰⽅式如:双亲表⽰法,孩⼦表⽰法、孩⼦双亲表⽰法以及孩⼦ 兄弟表⽰法等。我们这⾥就简单的了解其中最常⽤的孩⼦兄弟表⽰法

struct TreeNode { struct Node* child; // 左边开始的第⼀个孩⼦结点 struct Node* brother; // 指向其右边的下⼀个兄弟结点 int data; // 结点中的数据域 };

1.4 树形结构实际运⽤场景 ⽂件系统是计算机存储和管理⽂件的⼀种⽅式,它利⽤树形结构来组织和管理⽂件和⽂件夹。在⽂件 系统中,树结构被⼴泛应⽤,它通过⽗结点和⼦结点之间的关系来表⽰不同层级的⽂件和⽂件夹之间 的关联。

2. ⼆叉树

2.1 概念与结构

在树形结构中,我们最常⽤的就是⼆叉树,⼀棵⼆叉树是结点的⼀个有限集合,该集合由⼀个根结点 加上两棵别称为左⼦树和右⼦树的⼆叉树组成或者为空。

从上图可以看出⼆叉树具备以下特点:

  • 1. ⼆叉树不存在度⼤于 2 的结点
  • 2. ⼆叉树的⼦树有左右之分,次序不能颠倒,因此⼆叉树是有序树

2.2 特殊的⼆叉树

满二叉树和名字一样,就是每层的节点数都到达最大数。

⼀个⼆叉树,如果每⼀个层的结点数都达到最⼤值,则这个⼆叉树就是满⼆叉树。也就是说,如果⼀ 个⼆叉树的层数为 K ,且结点总数是2^k-1.

2.2.2 完全⼆叉树

完全二叉树和满二叉树又不同,完全⼆叉树是效率很⾼的数据结构,完全⼆叉树是由满⼆叉树⽽引出来的。对于深度为 K 的,有 n 个 结点的⼆叉树,当且仅当其每⼀个结点都与深度为K的满⼆叉树中编号从 1 ⾄ n 的结点⼀⼀对应时称 之为完全⼆叉树。要注意的是满⼆叉树是⼀种特殊的完全⼆叉树。

2.3 ⼆叉树存储结构

2.3.1 顺序结构

无非就创建一个数组,挨个存 二叉树的数据,根节点无疑是0,然后他的两个孩子节点就是1和2,1的两个孩子节点就是4和5,以此类推。

2.3.2 链式结构

链式结构更容易想象到,就是每个节点有两个指向,一个指向左孩子,一个指向右孩子,然后每个节点都存储数据。

3. 实现顺序结构⼆叉树

顺序结构实现二叉树一般使用堆的方式,

堆又分为大堆和小堆

  • 小堆:根节点是最小的数据,每个节点都比他的父节点大
  • 大堆:和小堆刚相反,根节点最大,每个节点都比父节点大

 并且堆是一种完全而二叉树

3.2 堆的实现

头文件Heap.h

#include<stdio.h> #include<stdlib.h> #include<stdbool.h> #include<assert.h> typedef int HPDataType; typedef struct Heap { HPDataType* arr; int size; int capacity; }HP; void HPInit(HP* php); void HPPush(HP* php,HPDataType x); void HPPop(HP* php); void HPDestory(HP* php); bool HPEmpty(HP* php); 

Heap.c

#include"Heap.h" void HPInit(HP* php) { php->arr = NULL;//你的初始化有问题,这里size是多少你自己想想看呢 php->capacity = php->size=0; } void Swap(int* x, int* y) { int* tmp = *x; *x = *y; *y = *x; } void AdjustUp(HP* php) { int child = php->size - 1; int parent = (php->size - 1) / 2; while (child>0) { if (php->arr[parent] > php->arr[child]) { Swap(&php->arr[parent], &php->arr[child]); child = parent; parent = (child - 1) / 2; } else { break; } } } void HPPush(HP* php, HPDataType x) { assert(php); //判断空间是否足够 if (php->size == php->capacity) { //扩容 int newCapacity = php->capacity == 0 ? 4 : 2 * php->capacity;//所以到了这边你的cap也有问题导致你后面realloc出错 HPDataType* tmp = (HPDataType*)realloc(php->arr, newCapacity * sizeof(HPDataType)); if (tmp == NULL) { perror("realloc fail!"); exit(1); } php->arr = tmp; php->capacity = newCapacity; } php->arr[php->size] = x; AdjustUp(php); ++php->size; } void AdjustDown(HP* php) { int parent = 0; int child = 2 * parent + 1; while (child < php->size) { if (child + 1 < php->size && php->arr[child] > php->arr[child + 1]) { child++; } if (php->arr[parent] > php->arr[child]) { Swap(&php->arr[parent], &php->arr[child]); parent = child; child = parent * 2 + 1; } else { break; } } } void HPPop(HP* php) { Swap(&php->arr[0], &php->arr[php->size-1]); --php -> size; AdjustDown(php); } bool HPEmpty(HP* php) { assert(php); return php->size == 0; } void HPDestory(HP* php) { if (php->arr) free(php->arr); php->arr = NULL; php->size = php->capacity = 0; }

 3.2.2 向下调整算法

就是在删除堆顶的时候,将堆顶与最后一个元素进行交换,然后php->size--,从根节点挨个开始比较下一个节点的大小。

Read more

8个降AI率工具推荐!本科生高效降AIGC神器合集

8个降AI率工具推荐!本科生高效降AIGC神器合集

8个降AI率工具推荐!本科生高效降AIGC神器合集 AI降重工具:让论文更自然,让学术更安心 在当前高校学术规范日益严格的背景下,越来越多的本科生开始关注“论文降AIGC率”和“去AI痕迹”的问题。随着AI写作工具的广泛应用,许多学生在使用这些工具完成初稿后,发现论文的AIGC检测率偏高,影响了最终成绩。这时候,一款高效的AI降重工具就显得尤为重要。 优秀的AI降重工具不仅能够有效降低论文的AIGC率,还能在不改变原意的前提下,优化语言表达,使论文更加符合学术规范。同时,这些工具往往具备强大的查重功能,能帮助学生提前发现潜在重复内容,从而进行针对性修改。无论是面对学校要求的查重系统,还是国际通用的检测平台,这些工具都能提供可靠的支持。 工具名称主要功能适用场景千笔强力去除AI痕迹、保语义降重AI率过高急需降重云笔AI多模式降重初稿快速处理锐智 AI综合查重与降重定稿前自查文途AI操作简单片段修改降重鸟同义词替换小幅度修改笔杆在线写作辅助辅助润色维普官方查重最终检测万方数据库查重数据对比 千笔AI(官网直达入口) :https://www.qianbixiezuo.c

By Ne0inhk

对于VScode中Copilot插件使用卡顿问题的解决办法

copilot卡顿主要是网络和内存占用原因。 VScode内存优化解决办法: 结合链接和我补充的基本都可以解决。 解决VSCode无缘无故卡顿的问题_vscode卡顿-ZEEKLOG博客 在VScode中打开setting.json文件,打开方法ctrl+shift+p,输入Preferences: Open User Settings (JSON), 然后添加如下代码: { "search.followSymlinks": false, "git.autorefresh": false, "editor.formatOnSave": false } 结合链接和我补充的基本都可以解决。 VScode代理问题: vscode copilot长时间没反应_vscode中copilot总是卡住-ZEEKLOG博客 配置代理的话两种方法,上面是一种,推荐两种结合起来用(不冲突) 还是在setting.json文件中,添加如下代码: { "http.proxy": "http://127.

By Ne0inhk

使用LLama.cpp本地部署大模型

摘要         llama.cpp是一个基于C/C++开发的高效大语言模型推理工具,支持跨平台部署和Docker快速启动,核心功能是在有限的计算资源情况下本地部署使用大模型。本文介绍了通过Docker方式部署llama.cpp的步骤,包括如何下载模型、CPU/GPU配置及启动参数说明。llama.cpp提供Web UI界面和OpenAI兼容API,支持文本和多模态对话,对电脑配置要求不高,完全免费且私密,让普通用户也能轻松在本地运行大语言模型。 LLama.cpp简介        1. llama.cpp 是一个在 C/C++ 中实现大型语言模型(LLM)推理的工具         2.支持跨平台部署,也支持使用 Docker 快速启动         3.可以运行多种量化模型,对电脑要求不高,CPU/GPU设备均可流畅运行。         支持模型包含:llama系列,qwen系列,gemma系列,Falcon、Alpaca、GPT4All、Chinese LLaMA、Vigogne、

By Ne0inhk
PaperZZ 降重 / 降 AIGC 功能:如何把 “AI 痕迹 + 高重复率” 拧成 “可通过知网 / 维普的原创文本”?——2026 届毕业生的学术合规指南

PaperZZ 降重 / 降 AIGC 功能:如何把 “AI 痕迹 + 高重复率” 拧成 “可通过知网 / 维普的原创文本”?——2026 届毕业生的学术合规指南

Paperzz-AI官网免费论文查重复率AIGC检测/开题报告/文献综述/论文初稿 (注:本文聚焦工具辅助学术写作的合规优化,所有内容需结合研究者原创思考使用,严格遵守学术诚信与院校规范) 一、论文提交前的 “双重焦虑”:你在为 “AI 痕迹 + 高重复率” 彻夜难眠? 论文提交前的崩溃,往往不是 “研究没做完”,而是卡在 “AI 生成痕迹被检测” 和 “重复率超标” 的双重困境里: * 用 AI 写的初稿,维普检测显示 AIGC 相似度 99.8%,被导师打回 “必须消除 AI 痕迹”; * 手动改了 3 遍,重复率从 35% 降到 28%,还是过不了学校 “≤20%” 的红线; * 改到最后,句子变得不通顺、专业术语全丢,

By Ne0inhk