初级数据结构——树

目录

  • 前言
  • 一、树的基本概念
  • 二、二叉树
  • 三、树的表示方法
  • 四、树的遍历
  • 树的代码模版
  • 五、经典例题
    • [2236. 判断根结点是否等于子结点之和](https://leetcode.cn/problems/root-equals-sum-of-children/description/)
      • 代码题解
  • 六、总结
  • 结语

前言

从这一期开始数据结构开始有那么一点复杂了,这期我们一起来学习初级数据结构——树,树是数据结构中的一个重要概念,它用于表示具有层次关系的数据集合。
在这里插入图片描述

一、树的基本概念

定义:树是一种非线性的数据结构,由n(n>=0)个有限节点组成一个具有层次关系的集合。它看起来像一棵倒挂的树,根朝上,叶朝下。

特殊节点:
根节点:树中唯一的特殊节点,没有前驱节点。
子节点:根节点外的其余节点,被分成M(M>0)个互不相交的集合,每个集合又是一棵子树。
叶子节点:度为0的节点,即没有子节点的节点。
分支节点:度不为0的节点,即含有子节点的节点。
节点关系
双亲节点(父节点):若一个节点含有子节点,则这个节点称为其子节点的父节点。
孩子节点(子节点):一个节点含有的子树的根节点称为该节点的子节点。
兄弟节点:具有相同父节点的节点互称为兄弟节点。
堂兄弟节点:双亲在同一层的节点互为堂兄弟。
祖先节点:从根到该节点所经分支上的所有节点。
子孙节点:以某节点为根的子树中任一节点都称为该节点的子孙。
树的度:树中节点的最大度,即节点的最大子树数。
树的层次:从根开始定义起,根为第1层,根的子节点为第2层,以此类推。
树的高度(深度):树中节点的最大层次。

二、二叉树

定义:二叉树是节点的一个有限集合,该集合为空或由一个根节点加上两棵别称为左子树和右子树的二叉树组成。二叉树的子树有左右之分,次序不能颠倒。

特殊二叉树
满二叉树:每一层上的节点数都是最大节点数,即每一层i的节点数都是2^i。
完全二叉树:叶子节点只能在层次最大的两层上出现,且对任一节点,若其右分支的子孙的最大层次为l,则其左分支的子孙的最大层次必是l或l+1。完全二叉树可以由满二叉树引伸出来,是效率很高的数据结构。

二叉树的性质:
在二叉树的第i层上至多有2^(i-1)个节点(i>=1)。
深度为k的二叉树至多有2^k-1个节点(k>=1)。
对于任何一颗二叉树,其叶子节点数为n0,度为2的节点数为n2,则n0=n2+1。
具有n个节点的完全二叉树的深度为log2n+1(向下取整,n>0)。

二叉树的存储结构:
顺序存储结构:使用数组来存储,一般适合表示完全二叉树。对于非完全二叉树,可能会造成空间浪费。
链式存储结构:用链表来表示二叉树,链表中的每个节点由数据域和左右指针域组成,左右指针分别用来给出该节点左孩子和右孩子所在的链节点的存储地址。链式结构又分为二叉链和三叉链。

三、树的表示方法

树有多种表示方法,包括树形表示法、孩子兄弟表示法、文氏图表示法、凹形表示法、括号表示法等。其中,树形表示法是最常用的方法,每个节点指向若干孩子节点,以此类推。

四、树的遍历

树的遍历是指按照某种规则访问树中的每个节点,使得每个节点被访问且仅被访问一次。常见的遍历方法包括先根遍历、后根遍历和中序遍历(针对二叉树)。

先根遍历:先遍历根节点再遍历它的子节点。
后根遍历:先遍历子节点再遍历根节点。
中序遍历(针对二叉树):先访问左子树,再访问根,再访问右子树。

树的代码模版

#include<iostream>
using namespace std;

template<typename T>
struct ListNode {
	T data;
	ListNode* next;
	ListNode(T x):data(x),next(NULL){}
};

template<typename T>
struct TreeNode {
	T data;
	ListNode<TreeNode<T>*>* childrenHead;//子节点指针
	TreeNode() {
		childrenHead = NULL;
	}
	void Addchild(TreeNode<T>* node) {//增加子节点的接口
		ListNode<TreeNode<T>*>* childNode = new ListNode<TreeNode<T>*>(node);
		if (childrenHead == NULL) childrenHead = childNode;
		else {
			childNode->next = childrenHead;
			childrenHead = childNode;
		}
	}
};

template<typename T>
class Tree {
private:
	TreeNode<T>* root;
	TreeNode<T>* nodes;
public:
	Tree();
	Tree(int maxNode);
	~Tree();
	TreeNode<T>* getTreeNode(int id);
	void setRoot(int rootId);
	void AddChild(int sonId, int parentId);
	void AssignData(int nodeId, T data);
	void Print(TreeNode<T>* node = NULL);
};

template<typename T>
Tree<T>::Tree() {
	nodes = new TreeNode<T>[100001];
}

template<typename T>
Tree<T>::Tree(int maxNodes) {
	nodes = new TreeNode<T>[maxNodes];
}

template<typename T>
Tree<T>::~Tree() {
	delete[]nodes;
}

template<typename T>
TreeNode<T>* Tree<T>::getTreeNode(int id) {
	return &nodes[id];
}

template<typename T>
void Tree<T>::setRoot(int rootId) {
	root = getTreeNode(rootId);
}

template<typename T>
void Tree<T>::AddChild(int parentId, int sonId) {
	TreeNode<T>* parentNode = getTreeNode(parentId);
	TreeNode<T>* sonNode = getTreeNode(sonId);
	parentNode->Addchild(sonNode);
}

template<typename T>
void Tree<T>::AssignData(int nodeId, T data) {
	getTreeNode(nodeId)->data = data;
}

template<typename T>
void Tree<T>::Print(TreeNode<T>* node) {
	if (node == NULL)node = root;
	cout << node->data;
	ListNode<TreeNode<T>*>* temp = node->childrenHead;
	while (temp) {
		Print(temp->data);
		temp = temp->next;
	}
}
int main() {
	Tree<char>t(9);
	t.setRoot(0);
	t.AssignData(0, 'a');
	t.AssignData(1, 'b');
	t.AssignData(2, 'c');
	t.AssignData(3, 'd');
	t.AssignData(4, 'e');
	t.AssignData(5, 'f');
	t.AssignData(6, 'g');
	t.AssignData(7, 'h');
	t.AssignData(8, 'i');

	t.AddChild(0, 2);
	t.AddChild(0, 1);
	t.AddChild(1, 3);
	t.AddChild(2, 5);
	t.AddChild(2, 4);
	t.AddChild(3, 8);
	t.AddChild(3, 7);
	t.AddChild(3, 6);

	t.Print();
	return 0;
}

五、经典例题

2236. 判断根结点是否等于子结点之和

(蓝色字体可以点进去看原题)

代码题解

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    bool checkTree(TreeNode* root) {
        return root->val==root->left->val+root->right->val;
    }
};

六、总结

综上所述,树是一种重要的数据结构,它用于表示具有层次关系的数据集合。在树的基础上,还可以构建出更复杂的树形结构,如二叉树、B树、B+树等,以满足不同的应用需求。

结语

下期我们将一起学习初级数据结构——二叉树,我们这期不见不散

在这里插入图片描述

想看更多内容可以关注我,看我作品,关注我让我们一起学习编程,希望大家能点赞关注支持一下,让我有持续更新的动力,谢谢大家

在这里插入图片描述

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

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

相关文章

Unity 编辑器下 Android 平台 Addressable 加载模型粉红色,类似材质丢失

Unity 编辑器下 Android 平台 Addressable 加载模型粉红色&#xff0c;类似材质丢失 Addressable Play Mode Script加载模式 选择 Use Existiing Build 1.Unity 切换到 PC 平台&#xff0c;执行 Addressable Build 运行&#xff0c;加载 bundle 内的预制体 显示正常 2.Unit…

视频去重工具

视频去重工具 工具截图 下载 回复&#xff1a;“0028”&#xff0c;即可自动获取

javascrip页面交互

元素的三大系列 offset系列 offset初相识 offset系列属性 作用 element.offsetParent 返回作为该元素带有定位的父级元素&#xff0c;如果父级没有定位&#xff0c;则返回body element.offsetTop 返回元素相对于有定位父元素上方的偏移量 element.offsetLeft 返回元素…

win10中使用ffmpeg和MediaMTX 推流rtsp视频

在win10上测试下ffmpeg推流rtsp视频&#xff0c;需要同时用到流媒体服务器MediaMTX 。ffmpeg推流到流媒体服务器MediaMTX &#xff0c;其他客户端从流媒体服务器拉流。 步骤如下&#xff1a; 1 下载MediaMTX github: Release v1.9.3 bluenviron/mediamtx GitHub​​​​​…

el-select 和el-tree二次封装

前言 本文章是本人在开发过程中&#xff0c;遇到使用树形数据&#xff0c;动态单选或多选的需求&#xff0c;element中没有这种组件&#xff0c;故自己封装一个&#xff0c;欢迎多多指教 开发环境&#xff1a;element-UI、vue2 组件效果 单选 多选 组件引用 <treeselec…

STM32-- keil常见报错与解决办法

调试问题 1. keil在线调试需要点击好几次运行才可以运行&#xff0c;要是直接下载程序直接就不运行。 解决&#xff1a;target里面的use microlib要勾选&#xff0c;因为使用了printf。 keil在线调试STM32&#xff0c;点三次运行才能跑到main的问题解决。 keil在线调试STM32…

RNN简单理解;为什么出现Transformer:传统RNN的问题;Attention(注意力机制)和Self-Attention(自注意力机制)区别;

目录 RNN简单理解 RNN n to n Transformer N to M LSTM 为什么出现Transformer:传统RNN的问题 信息丢失的后果 Rnn是顺序执行的效率不高:顺序执行 Attention(注意力机制)和Self-Attention(自注意力机制)区别 一、计算对象不同 二、应用场景不同 三、功能差异…

51c深度学习~合集8

我自己的原文哦~ https://blog.51cto.com/whaosoft/12491632 #patchmix 近期中南大学的几位研究者做了一项对比学习方面的工作——「Inter-Instance Similarity Modeling for Contrastive Learning」&#xff0c;主要用于解决现有对比学习方法在训练过程中忽略样本间相似关系…

Kafka:分布式消息系统的核心原理与安装部署

Kafka&#xff1a;分布式消息系统的核心原理与安装部署-CSDN博客 自定义 Kafka 脚本 kf-use.sh 的解析与功能与应用示例-CSDN博客 Kafka 生产者全面解析&#xff1a;从基础原理到高级实践-CSDN博客 Kafka 生产者优化与数据处理经验-CSDN博客 Kafka 工作流程解析&#xff1a…

刷算法题时遇到的一些不常用但好用的API

1.需要统计数据&#xff0c;同时希望数据是排序的&#xff0c;可以使用TreeMap结构。 2.按照ASCII&#xff0c;A的ASCII值比a小。而字典排序底层也有基于ASCII&#xff0c;因此无论是字典排序还是ASCII排序&#xff0c;A都在a前面。 3.使用DecimalFormat尝试将浮点数四舍五入…

2024-11-19 kron积

若A[a11 a12; a21 a22]; B[b11 b12; b21 b22]; 则C[a11*b11 a12*b11 a21*b11 a22*b11; a11*b12 a12*b12 a21*b12 a22*b12; a11*b21 a12*b21 a21*b21 a22*b21; a11*b22 a12*b22 a21*b22 a22*b22] 用MATLAB实现 方法1&#xff1a; A [a11 a12; a21 a22]; B [b11 b12; b21 b22]…

工业生产安全-安全帽第二篇-用java语言看看opencv实现的目标检测使用过程

一.背景 公司是非煤采矿业&#xff0c;核心业务是采选&#xff0c;大型设备多&#xff0c;安全风险因素多。当下政府重视安全&#xff0c;头部技术企业的安全解决方案先进但价格不低&#xff0c;作为民营企业对安全投入的成本很敏感。利用我本身所学&#xff0c;准备搭建公司的…

(7) 探索Python函数的无限可能:从递归到Lambda的奇妙之旅

欢迎进入Python编程的奇幻世界!在这个课程中,我们将一起探索编程的乐趣,通过生动有趣的方式,培养编程的逻辑思维和创造力,该课程适合有一定基础的中学及以上学生及成年人。 以下是我们课程的大纲: 【Python:趣味编程,探索未来】 目录 1. 前言2. 认识我们的“魔法咒语”…

【深度学习|目标跟踪】DeepSort 详解

DeepSort详解 1、Sort回顾2、DeepSort的状态向量3、DeepSort的外观特征4、DeepSort的track状态5、DeepSort的代价矩阵以及门控矩阵6、DeepSort的级联匹配 1、Sort回顾 查看这篇博客 2、DeepSort的状态向量 Sort中的卡尔曼滤波使用的目标的状态向量是一个7维的向量&#xff0c…

MetaGPT实现多动作Agent

异步编程学习链接 智能体 LLM观察思考行动记忆 多智能体 智能体环境SOP评审路由订阅经济 教程地址 多动作的agent的本质是react&#xff0c;这包括了think&#xff08;考虑接下来该采取啥动作&#xff09;act&#xff08;采取行动&#xff09; 在MetaGPT的examples/write_…

重学SpringBoot3-Spring Retry实践

更多SpringBoot3内容请关注我的专栏&#xff1a;《SpringBoot3》 期待您的点赞&#x1f44d;收藏⭐评论✍ 重学SpringBoot3-Spring Retry实践 1. 简介2. 环境准备3. 使用方式3.1 注解方式基础使用自定义重试策略失败恢复机制重试和失败恢复效果注意事项 3.2 编程式使用3.3 监听…

E. Counting Arrays

题意&#xff1a;给定一个长度为n&#xff0c;要求乘积为m&#xff0c;其中组成m的数要求是整数 思路&#xff1a;首先有个很显然的想法&#xff1a;设表示前i个点乘积为j的最小值。因为询问数很多&#xff0c;所以必须离线把所有的东西都处理出来。 转移&#xff1a;&#x…

Leetcode 生命游戏

以下是上述Java代码的算法思想及其逻辑的中文解释&#xff1a; 算法思想 这段代码实现了LeetCode第289题“生命游戏”的解决方案。核心思想是&#xff1a; 利用原地修改的方式&#xff08;in-place&#xff09;存储下一状态的变化&#xff1a; 通过引入额外的状态值&#xff0…

文件管理 IV(文件系统)

一、文件系统结构 文件系统&#xff08;File system&#xff09;提供高效和便捷的磁盘访问&#xff0c;以便允许存储、定位、提取数据。文件系统有两个不同的设计问题&#xff1a;第一个问题是&#xff0c;定义文件系统的用户接口&#xff0c;它涉及定义文件及其属性、所允许的…

单神经元 PID 解耦控制

单神经元 PID 解耦控制是一种将单神经元自适应控制与解耦控制相结合的方法&#xff0c;适用于多输入多输出&#xff08;MIMO&#xff09;系统。其核心是利用单神经元的自适应能力实现 PID 参数在线调整&#xff0c;同时通过解耦策略减少变量之间的相互影响&#xff0c;提高控制…