数据结构学习笔记 :树与二叉树详解
目录
- 树的基本概念
- 二叉树的定义与特性
- 二叉树的存储结构
3.1 顺序存储
3.2 链式存储 - 二叉树遍历
- 特殊二叉树类型
- 总结与应用场景
一、树的基本概念
核心定义
- 树:由根节点和若干子树构成的层次结构。
- 叶子节点(终端节点):没有子节点的节点。
- 分支节点:有子节点的节点(根节点除外)。
- 树的高度:节点所在层次的最大值。
- 节点的度:子节点的数量;树的度:所有节点度的最大值。
树的性质
- 树中的结点数等于所有结点的度数之和加1。
- 度为
m的树的第i层最多有m^(i-1)个节点。 - 满二叉树与完全二叉树的特殊性质(见后文)。
二、二叉树的定义与特性
二叉树的定义
- 二叉树:每个节点最多有两个子节点(左子树和右子树)。
- 五种形态:
- 空树;
- 只有根节点;
- 根节点+左子树;
- 根节点+右子树;
- 根节点+左子树+右子树。
三、二叉树的存储结构
1. 顺序存储(数组实现)
#include <stdio.h>
#include <stdbool.h>
#define MaxSize 100
typedef int ElemType;typedef struct Tree {ElemType data[MaxSize]; // 数据域bool flag[MaxSize]; // 标记节点是否有效
} Tree;// 初始化
void InitTree(Tree *t) {for (int i = 0; i < MaxSize; i++) {t->flag[i] = false;}
}// 插入节点(构建二叉排序树)
bool insert_node(Tree *t, ElemType e) {int i = 1;while (i < MaxSize) {if (t->flag[i]) {if (t->data[i] >= e) {i = 2 * i; // 左子树方向} else {i = 2 * i + 1; // 右子树方向}} else {t->flag[i] = true;t->data[i] = e;return true;}}return false;
}// 查找节点
int find_tree(Tree *t, ElemType e) {int i = 1;while (i <= MaxSize) {if (t->flag[i]) {if (t->data[i] > e) {i = 2 * i; // 左子树方向} else if (t->data[i] < e) {i = 2 * i + 1; // 右子树方向} else {return i; // 找到返回编号}} else {return -1; // 未找到}}return -1;
}
2. 链式存储(动态节点)
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef int ElemType;typedef struct BitNode {ElemType data;struct BitNode *lchild, *rchild;
} BitNode, *BitTree;// 新建节点
BitNode* newnode(ElemType e) {BitNode* node = (BitNode*)malloc(sizeof(BitNode));if (!node) return NULL;node->data = e;node->lchild = node->rchild = NULL;return node;
}// 插入节点(构建二叉排序树)
bool insert_node(BitTree *t, BitNode *new) {if (*t == NULL) { // 空树插入根节点*t = new;return true;}BitNode *p = *t;while (1) {if (new->data < p->data) { // 左子树方向if (p->lchild == NULL) {p->lchild = new;return true;}p = p->lchild;} else if (new->data > p->data) { // 右子树方向if (p->rchild == NULL) {p->rchild = new;return true;}p = p->rchild;} else {return false; // 数据重复}}
}
四、二叉树遍历
三种遍历方式
- 前序遍历(根左右)
void PreOrder(BitNode *root) {if (root == NULL) return;printf("%d ", root->data);PreOrder(root->lchild);PreOrder(root->rchild);
}
- 中序遍历(左根右)
void MidOrder(BitNode *root) {if (root == NULL) return;MidOrder(root->lchild);printf("%d ", root->data);MidOrder(root->rchild);
}
- 后序遍历(左右根)
void PostOrder(BitNode *root) {if (root == NULL) return;PostOrder(root->lchild);PostOrder(root->rchild);printf("%d ", root->data);
}
五、特殊二叉树类型
1. 满二叉树
- 定义:高度为
h的二叉树有2^h - 1个节点。 - 特点:
- 除最后一层外,所有层的节点数达到最大。
- 无度为1的节点。
- 节点编号按层序从1开始,父节点
i的左右子节点分别为2i和2i+1。
2. 完全二叉树
- 定义:编号与满二叉树一致,即叶子节点仅出现在最后一层或倒数第二层。
- 性质:可高效用数组存储。
3. 二叉排序树(BST)
- 定义:左子树所有节点值 < 根节点值 < 右子树所有节点值。
- 应用:快速搜索、插入和删除操作(平均时间复杂度
O(log n))。
4. 平衡二叉树(AVL树)
- 定义:所有节点的左右子树高度差≤1。
- 作用:保证树的平衡性,避免退化为链表,确保操作效率。
六、总结与应用场景
核心总结
- 存储选择:
- 顺序存储:适合完全二叉树(如堆)。
- 链式存储:通用,支持动态扩展。
- 遍历用途:
- 前序:复制二叉树。
- 中序:对二叉排序树进行升序遍历。
- 后序:释放内存、计算表达式。
典型应用场景
- 二叉排序树:数据库索引、快速查找。
- 平衡二叉树:需要高效插入/删除的场景(如动态数据集合)。
- 堆(完全二叉树):优先队列实现。
希望这篇笔记能帮助读者掌握树与二叉树的核心概念及实现方法!
相关文章:
数据结构学习笔记 :树与二叉树详解
目录 树的基本概念二叉树的定义与特性二叉树的存储结构 3.1 顺序存储 3.2 链式存储二叉树遍历特殊二叉树类型总结与应用场景 一、树的基本概念 核心定义 树:由根节点和若干子树构成的层次结构。叶子节点(终端节点):没有子节点的…...
前沿篇|CAN XL 与 TSN 深度解读
引言 1. CAN XL 标准演进与设计目标 2. CAN XL 物理层与帧格式详解 3. 时间敏感网络 (TSN) 关键技术解析 4. CAN XL + TSN 在自动驾驶领域的典型应用...
七、LangChain Tool类参数对接机制解析:基于Pydantic的类型安全与流程实现
LangChain 的 Tool 类(包括 BaseTool 和 StructuredTool)通过 参数校验、输入解析、函数调用 的流程,将外部函数与 Agent 的逻辑对接。以下是其内部逻辑的详细解析: 1. 工具与函数对接的核心机制 (1) 工具的定义方式 LangChain 提供了两种主要方式定义工具: 继承 BaseTo…...
Spring-AI-alibaba 结构化输出
1、将模型响应转换为 ActorsFilms 对象实例: ActorsFilms package com.alibaba.cloud.ai.example.chat.openai.entity;import java.util.List;public record ActorsFilms(String actor, List<String> movies) { } GetMapping("/toBean")public Ac…...
AI大模型科普:从零开始理解AI的“超级大脑“,以及如何用好提示词?
大家好,小机又来分享AI了。 今天分享一些新奇的东西, 你有没有试过和ChatGPT聊天时,心里偷偷犯嘀咕:"这AI怎么跟真人一样对答如流?它真的会思考吗?" 或者刷到技术文章里满屏的"Token"…...
STM32单片机入门学习——第40节: [11-5] 硬件SPI读写W25Q64
写这个文章是用来学习的,记录一下我的学习过程。希望我能一直坚持下去,我只是一个小白,只是想好好学习,我知道这会很难,但我还是想去做! 本文写于:2025.04.18 STM32开发板学习——第一节: [1-1]课程简介第40节: [11-5] 硬件SPI读…...
【Java学习笔记】关键字汇总
Java 关键字汇总 用于定义数据类型的关键字: classinterfaceenumbyteshortintlongfloatdoublecharbooleanvoid 用于定义数据值的关键字: truefalsenull 用于定义流程控制的关键字: ifelseswitchcasedefaultwhiledoforbreakcontinueretu…...
langgraph框架之初识
1.什么是langgraph? LangGraph 是一个用于构建可控代理的底层编排框架。在AI中,代理也就是执行动作的智能体,也就是agent。使用这个框架可以构建一个可以自由控制的智能执行体,它可以帮我们做许多事情,如下࿱…...
如何将 .txt 文件转换成 .md 文件
一、因为有些软件上传文件的时候需要 .md 文件,首先在文件所在的目录中,点击“查看”,然后勾选上“文件扩展名”,这个时候该目录下的所有文件都会显示其文件类型了。 二、这时直接对目标的 .txt 文件进行重命名,把后缀…...
pdfjs库使用记录1
import React, { useEffect, useState, useRef } from react; import * as pdfjsLib from pdfjs-dist; // 设置 worker 路径 pdfjsLib.GlobalWorkerOptions.workerSrc /pdf.worker.min.js; const PDFViewer ({ url }) > { const [pdf, setPdf] useState(null); const […...
Qt 创建QWidget的界面库(DLL)
【1】新建一个qt库项目 【2】在项目目录图标上右击,选择Add New... 【3】选择模版:Qt->Qt设计师界面类,选择Widget,填写界面类的名称、.h .cpp .ui名称 【4】创建C调用接口(默认是创建C调用接口) #ifnd…...
Django REST framework 并结合 `mixin` 的示例
下面为你提供一个使用 Django REST framework 并结合 mixin 的示例,该示例将实现一个简单的图书管理 API。 项目需求 我们要创建一个图书管理系统的 API,支持对图书信息的创建、读取、更新和删除操作。 实现步骤 1. 项目初始化 首先,确保你已经安装了 Django 和 Django…...
linux查看及修改用户过期时间
修改用户有效期 密码到期时间 sudo chage -E 2025-12-31 username sudo chage -M 180 username sudo chage -d $(date %F) username 查询用户密码到期时间 for user in $(cat /etc/passwd |cut -d: -f1); do echo $user; chage -l $user | grep "Password expires"; …...
Vue.directive自定义v-指令
翻阅文章有感,记录学习 vue前端菜单权限控制_vue权限管理菜单思路-CSDN博客 一、定义:Vue.directive是Vue框架中给开发者用于注册自定义指令和返回已注册指令的API 二、基本语法: // 注册 Vue.directive(my-directive, {bind: function () …...
AI Agent 元年,于 2025 开启
私人博客传送门 AI Agent 元年,于 2025 开启 | 魔筝炼药师...
Django 自带开发服务器
$ python manage.py runserver $ python manage.py runserver 666 # 用 666 端口 $ python manage.py runserver 0.0.0.0:8000 # 让局域网内其他客户端也可访问 $ python manage.py runserver --skip-checks # 跳过检查自动检查 $ python manage.py runserver --…...
Spring 数据库编程
Spring JDBC 传统的JDBC在操作数据库时,需要先打开数据库连接,执行SQL语句,然后封装结果,最后关闭数据库连接等资源。频繁的数据库操作会产生大量的重复代码,造成代码冗余,Spring的JDBC模块负责数据库资源…...
进阶篇|CAN FD 与性能优化
引言 1. CAN vs. CAN FD 对比 2. CAN FD 帧结构详解...
CTF--各种绕过哟
一、原网页: 二、步骤: 1.源代码: <?php highlight_file(flag.php); $_GET[id] urldecode($_GET[id]); $flag flag{xxxxxxxxxxxxxxxxxx}; if (isset($_GET[uname]) and isset($_POST[passwd])) {if ($_GET[uname] $_POST[passwd])pr…...
【Pandas】pandas DataFrame where
Pandas2.2 DataFrame Indexing, iteration 方法描述DataFrame.head([n])用于返回 DataFrame 的前几行DataFrame.at快速访问和修改 DataFrame 中单个值的方法DataFrame.iat快速访问和修改 DataFrame 中单个值的方法DataFrame.loc用于基于标签(行标签和列标签&#…...
嵌入式ARM RISCV toolchain工具 梳理arm-none-eabi-gcc
嵌入式TOOLchain工具 梳理 简介 本文总结和梳理一下一些toolchain的规则和原理,方便后续跨平台的时候,给大家使用toolchain做一个参考。 解释如何理解arm-none-eabi-gcc等含义,以及如何一看就知道该用什么编译器。 当然如果有哪里写的不是…...
OpenBMC:BmcWeb log输出
BmcWeb的log函数定义于:http\logging.hpp 说实话,个人觉得这一版的log函数有点炫技,使用起来也没有之前的版本方便,不过也还是值的参考一下。 1.如何输出log BMCWEB_LOG_ERROR("GetAll on path {} iface {} service {} failed with code {}",objectPath, inte…...
复现SCI图像增强(Toward fast, flexible, and robust low-light image enhancement.)
运行train.py报错 > File "/home/uriky/桌面/SCI-main/SCI-main/train.py", line 105, in main > train_queue torch.utils.data.DataLoader( File "/home/uriky/anaconda3/envs/AA/lib/python3.8/site-packages/torch/utils/data/dataloader.py&q…...
深入理解C++中string的深浅拷贝
目录 一、引言 二、浅拷贝与深拷贝的基本概念 2.1 浅拷贝 2.2 深拷贝 在C 中, string 类的深浅拷贝有着重要的区别。 浅拷贝 深拷贝 string 类中的其他构造函数及操作 resize 构造 构造(赋值构造) 构造(拼接构造…...
性能测试面试题的详细解答
以下是性能测试面试题的详细解答: 1. 性能测试的流程是怎样的? 性能测试流程通常包括以下几个步骤: - **需求分析**:明确测试目标、性能指标(如响应时间、吞吐量等)。 - **环境搭建**:搭建测试环…...
第八篇:系统分析师第三遍——3、4章
目录 一、目标二、计划三、完成情况四、意外之喜(最少2点)1.计划内的明确认知和思想的提升标志2.计划外的具体事情提升内容和标志 五、总结 一、目标 通过参加考试,训练学习能力,而非单纯以拿证为目的。 1.在复习过程中,训练快速阅读能力、掌…...
Unity粒子特效打包后不显示
1.粒子发mesh,如果打包后不显示,尝试勾选r/w 2.如果还不行,mesh重做,目前发现ab包打出的,有的mesh会出问题,暂时原因不详。...
PFC 是什么?
现在进行液晶电视机和等离子电视机电路分析时、故障维修时,都经常的提到“PFC 电路”一词,这 在早期的电视机中是没有的,早期维修电视机的师傅从来没有接触过的,但是 PFC 电路是目前液晶电视机 和等离子电视机中不可缺少的电路。那…...
6.5 GitHub监控系统实战:双通道采集+动态调度打造高效运维体系
GitHub Sentinel Agent 定期更新功能设计与实现 关键词:GitHub API 集成、定时任务调度、Python 爬虫开发、SMTP 邮件通知、系统稳定性保障 1. GitHub 项目数据获取功能 1.1 双通道数据采集架构设计 #mermaid-svg-ZHJIMXcMAyDHVhmV {font-family:"trebuchet ms",v…...
楼梯上下检测数据集VOC+YOLO格式5462张2类别
数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):5462 标注数量(xml文件个数):5462 标注数量(txt文件个数):5462 …...
