树与二叉树 —— 十分钟吊打数据结构

简介: 手撕树与二叉树结构带你一命通关,分分钟拿捏数据结构。

树的的概念与结构🤔

树是个甚么?和现实中的数差不多,有根有茎有枝有叶,长的和向下延伸的树根差不多,也可以看成一棵倒立的树,==树是一种非线性数据结构,由 n(n>=0)个有限节点组成一个具有层次关系的集合,具象一下就类似这样:
在这里插入图片描述
他有一个特殊的节点,称为根节点,也就是上图的 A 节点,除根节点外其余节点都被分成 M 个不相交的集合,每个集合又是一棵结构与树类似的子树,每棵子树根节点有且只有一个,后继节点可以是 0 个或者多个。因此,树是递归定义的。

这里就又需要思考递归的含义,递归是当前问题和子问题的集合,这里的树是根和n个子树构成,而每个子树的结构又是如此,开始逐渐套娃,直到遇到“叶子”结束。

注意,树与非树的区别就在于:

  1. ==树结构的子树是互不相交的(带回路的结构叫图)==
  2. ==除了根节点外,其余节点有且仅有一个父节点==
  3. ==一颗有N个节点的数有N-1条边==

在这里插入图片描述

基本术语🤔

不理解这些基本概念后面没法玩儿捏,还是得知道怎么去描述:

  1. 结点的度:结点的子树个数;
  2. 树的度:树的所有结点中最大的度数;
  3. 父结点:有子树的结点是其子树的根节点的父结点;
  4. 子结点:若A结点是B结点的父结点,则称B结点是A结点的子结点;
  5. 兄弟(姐妹)结点:具有同一个父结点的各结点彼此是兄弟结点(还有堂兄弟(姐妹)节点,自己意会就行懒得打字);
  6. 祖先结点:沿树根到某一结点路径上的所有结点
  7. 子孙结点:某一结点的子树中的所有结点
  8. 结点的层次:规定根结点在1层,其他任一结点的层数是其父结点的层数加1;

    1. 森林:由m(m>0)棵互不相交的树的集合称为森林

在这里插入图片描述

树的表示🤔

树要进行表示可不好表示,因为有一个大问题——==子节点个数不确定==。

这里树必然是一个链式结构,每个节点都有存的值以及指向孩子的指针,现在我们所使用的结构大多为顺序表,有人会用数组来搞(下标为孩子个数),也可以使用C++语法的 vector 来进行操作,但这些都只能算是中规中矩,这里介绍一种很优秀的表示方法可以不用关心度的多少和空间的消耗:孩子&兄弟表示法。

在强调一遍,这个结构表示树是最优秀的,没有之一!

typedef int datatype;
struct node
{
struct node* first;//第一个孩子节点
struct node* next;//指向下一个兄弟节点
datatype data;//数据域
}

来说明一下,随便以一个数结构为例:
在这里插入图片描述
A 的第一个孩子是B,则 first 指向B,而 A 的其他孩子怎么办呢?A 会先抛开不管,父母的二胎总喜欢叫老大来带,压力来到了 B 的身上, B 的 next 指向他的兄弟节点 C,也就是 A 的另一个孩子, C 没有兄弟了,就可以甩手无后顾之忧,他的 next 指向 NULL。

==总结一下就是父亲指向第一个孩子,其余的都用孩子的兄弟指针链接起来即可==,掌握了这个道理,无论多少孩子都无所谓,随便你玩儿。
在这里插入图片描述

树的实际应用🤔

树可以用来表示文件系统的目录树结构,比如最常见的:
在这里插入图片描述
其实这只是一种显示方式,目录树要依赖于其他主体,并不是内容本身,在Word ,Excel,Notepad++ 等平台都是不一样的。
在这里插入图片描述

二叉树🤔

二叉树这位重量级,各位多多少少有所耳闻吧,今天就换他来认识认识你。

二叉树就是一个度为 2 的树,即每个节点最多有两个子节点,当然,二叉树存在两个子节点时,节点有左右之分,顺序是绝对的,因此二叉树也是个有序树。

这里也介绍一下几个特殊的二叉树:
1. 斜二叉树
在这里插入图片描述

2. 满二叉树
在这里插入图片描述

每一层的节点都到达了最大值,层数为 n,那他的节点数就是 2^n-1 个(本质就是一个等比数列)。

3. 完全二叉树
在这里插入图片描述

这是一种效率贼高的数据结构,满二叉树是特殊的完全二叉树,完全二叉树由满二叉树引申出来,即(n-1)层都是满的,最后一层不满,但必须是从左到右挨的严严实实的。他们的优势就是用来表示一种数据结构——堆。

==那么问题来了,现在这里存了一堆数,这一堆数中谁是谁的左孩子,谁又是谁的右孩子呢?==

我们用数学关系是可以表示出来的,益父子节点的下标为关系计算:

父节点 = (子节点-1)/2;
左孩子节点:父节点 * 2 +1;
右孩子节点:父节点 * 2 + 2;

你可能会疑惑为什么父节点没有根据左孩子和右孩子来计算,原因很简单,不管是奇数还是偶数,相邻两个减1除2的结果是相同的。

二叉树的性质🤔

  1. 若规定根节点的层数为1,则一棵非空二叉树的第 n 层最多有2^(n-1)个节点;
  2. 若规定根节点的层数为1,则深度为 h 的二叉树最大结点数为 (2^h) -1;
  3. 任意二叉树,度为0的节点比度为 2 的节点永远多 1 个;
  4. 具有n个节点的完全二叉树深为log2x+1(其中x表示不大于n的最大整数);
  5. 如果对一颗有n个结点的完全二叉树(其深度为[log2n]+1)的结点按层序编号(从第一层到[log2n]+1层,每层从左到右),对任一结点i(1<= i <=n):

(1)如果i=1,则结点i是二叉树的根,无双亲,如果i>1,则其双亲结点是结点 i/2
(2)如果2i>n,则结点i无左孩子(结点i为叶子结点)否则左孩子是结点 2i。
(3)如果2i+1>n,则结点i无右孩子,否则其右孩子是结点2i+1。

在这里插入图片描述

相关文章
|
23天前
|
存储 算法 C语言
"揭秘C语言中的王者之树——红黑树:一场数据结构与算法的华丽舞蹈,让你的程序效率飙升,直击性能巅峰!"
【8月更文挑战第20天】红黑树是自平衡二叉查找树,通过旋转和重着色保持平衡,确保高效执行插入、删除和查找操作,时间复杂度为O(log n)。本文介绍红黑树的基本属性、存储结构及其C语言实现。红黑树遵循五项基本规则以保持平衡状态。在C语言中,节点包含数据、颜色、父节点和子节点指针。文章提供了一个示例代码框架,用于创建节点、插入节点并执行必要的修复操作以维护红黑树的特性。
45 1
|
5天前
|
存储 机器学习/深度学习
【数据结构】二叉树全攻略,从实现到应用详解
本文介绍了树形结构及其重要类型——二叉树。树由若干节点组成,具有层次关系。二叉树每个节点最多有两个子树,分为左子树和右子树。文中详细描述了二叉树的不同类型,如完全二叉树、满二叉树、平衡二叉树及搜索二叉树,并阐述了二叉树的基本性质与存储方式。此外,还介绍了二叉树的实现方法,包括节点定义、遍历方式(前序、中序、后序、层序遍历),并提供了多个示例代码,帮助理解二叉树的基本操作。
34 13
【数据结构】二叉树全攻略,从实现到应用详解
|
2天前
|
存储 算法 C语言
数据结构基础详解(C语言): 二叉树的遍历_线索二叉树_树的存储结构_树与森林详解
本文从二叉树遍历入手,详细介绍了先序、中序和后序遍历方法,并探讨了如何构建二叉树及线索二叉树的概念。接着,文章讲解了树和森林的存储结构,特别是如何将树与森林转换为二叉树形式,以便利用二叉树的遍历方法。最后,讨论了树和森林的遍历算法,包括先根、后根和层次遍历。通过这些内容,读者可以全面了解二叉树及其相关概念。
|
2天前
|
存储 机器学习/深度学习 C语言
数据结构基础详解(C语言): 树与二叉树的基本类型与存储结构详解
本文介绍了树和二叉树的基本概念及性质。树是由节点组成的层次结构,其中节点的度为其分支数量,树的度为树中最大节点度数。二叉树是一种特殊的树,其节点最多有两个子节点,具有多种性质,如叶子节点数与度为2的节点数之间的关系。此外,还介绍了二叉树的不同形态,包括满二叉树、完全二叉树、二叉排序树和平衡二叉树,并探讨了二叉树的顺序存储和链式存储结构。
|
2天前
|
存储 C语言
数据结构基础详解(C语言): 树与二叉树的应用_哈夫曼树与哈夫曼曼编码_并查集_二叉排序树_平衡二叉树
本文详细介绍了树与二叉树的应用,涵盖哈夫曼树与哈夫曼编码、并查集以及二叉排序树等内容。首先讲解了哈夫曼树的构造方法及其在数据压缩中的应用;接着介绍了并查集的基本概念、存储结构及优化方法;随后探讨了二叉排序树的定义、查找、插入和删除操作;最后阐述了平衡二叉树的概念及其在保证树平衡状态下的插入和删除操作。通过本文,读者可以全面了解树与二叉树在实际问题中的应用技巧和优化策略。
|
2天前
|
存储 C语言
数据结构基础详解(C语言): 栈与队列的详解附完整代码
栈是一种仅允许在一端进行插入和删除操作的线性表,常用于解决括号匹配、函数调用等问题。栈分为顺序栈和链栈,顺序栈使用数组存储,链栈基于单链表实现。栈的主要操作包括初始化、销毁、入栈、出栈等。栈的应用广泛,如表达式求值、递归等场景。栈的顺序存储结构由数组和栈顶指针构成,链栈则基于单链表的头插法实现。
|
4天前
|
Java
【数据结构】栈和队列的深度探索,从实现到应用详解
本文介绍了栈和队列这两种数据结构。栈是一种后进先出(LIFO)的数据结构,元素只能从栈顶进行插入和删除。栈的基本操作包括压栈、出栈、获取栈顶元素、判断是否为空及获取栈的大小。栈可以通过数组或链表实现,并可用于将递归转化为循环。队列则是一种先进先出(FIFO)的数据结构,元素只能从队尾插入,从队首移除。队列的基本操作包括入队、出队、获取队首元素、判断是否为空及获取队列大小。队列可通过双向链表或数组实现。此外,双端队列(Deque)支持两端插入和删除元素,提供了更丰富的操作。
10 0
【数据结构】栈和队列的深度探索,从实现到应用详解
|
26天前
栈的几个经典应用,真的绝了
文章总结了栈的几个经典应用场景,包括使用两个栈来实现队列的功能以及利用栈进行对称匹配,并通过LeetCode上的题目示例展示了栈在实际问题中的应用。
栈的几个经典应用,真的绝了
|
8天前
|
Linux C++ Windows
栈对象返回的问题 RVO / NRVO
具名返回值优化((Name)Return Value Optimization,(N)RVO)是一种优化机制,在函数返回对象时,通过减少临时对象的构造、复制构造及析构调用次数来降低开销。在C++中,通过直接在返回位置构造对象并利用隐藏参数传递地址,可避免不必要的复制操作。然而,Windows和Linux上的RVO与NRVO实现有所不同,且接收栈对象的方式也会影响优化效果。
|
24天前
|
负载均衡 网络协议 安全
DKDP用户态协议栈-kni
DKDP用户态协议栈-kni