DS二叉树基础

前言

我们好久没有更新数据结构的博文了,今天来更新一期树!前几期我们已经介绍了顺序表、链表,栈和队列等基本的线性数据结构并对其分别做了实现,本期我们再来介绍一个灰常重要的非线性基本结构 ---- 树型结构。

本期内容介绍

树的概念和结构

二叉树的概念和结构

一、树的概念和结构

树的概念

是一种线性(逻辑上非连续)的数据结构,它是由n(n >= 0)个有限结点组成的一个具有层次关系的集合!把他称为树是因为它的逻辑结构和一颗倒挂的树相似!

注意点:

(1)树中有一个特殊的结点被称为根节点,根节点没有前驱结点

(2)除了根节点以外,其余结点被分成了M(M > 0)个互不相交的集合(即子树之间不能相交)!其中每个集合又是一颗结构与树类似的子树!每颗子树的根结点有且只有一个前驱,可以有0个或多个后继!

所以综上树是更合适用递归定义的!

OK,画个图来理解一下:

注意:

树形结构中,子树与子树是不能相交的,如果相交就是我们后期介绍的图了!

除了根结点外,其余结点有且只有一个父节点

一个N个节点的树有N-1条边

树的相关概念

节点的度:一个节点含有的子树的个数被称为该节点的度;

叶子节点(终端节点度为0的节点称为叶子结点;

非终端节点(分支节点度不为0的节点

父亲节点(双亲节点:若一个节点含有子节点,则这个节点称为其子节点的父节点;

子节点(孩子节点):一个节点含有的子树的根节点称为该节点的子节点;

兄弟节点具有相同父节点的节点互称为心底节点;

树的度:一棵树中,最大节点的度被称为树的度。

节点的层次:从根节点开始定义第一层,根的子节点为第二层,依次类推!

树的高度(深度):树中节点的最大层次;

堂兄弟节点:双亲在同层的节点互成称堂兄弟节点;

节点的祖先从根到该节点所经分支上的所有节点;

子孙:以某节点为根的子树中任一节点都称为该节点的子孙;

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


树的表示

树结构相较于线性结构就复杂了,要存储起来也比较麻烦!既要存储值域,也要存储结点之间的关系!树的表示方式有很多种例如:双亲表示法、孩子表示法、孩子双亲表示法、孩子双亲表示法

这里大概介绍一下,后面重要的会在介绍例如双亲表示法(并查集)和孩子表示法(图的邻接表)!

双亲表示法是:用数组存储每个节点,每个节点中存入他们的父亲节点的下标!

孩子表示法:采用顺序表个链表进行存储,顺序表存各个节点,每个节点中保存第一个孩子的头指针

这些其实都不是最优结构,最优结构是下面我要介绍的这个----孩子兄弟表示法!

孩子兄弟表示法:有两个指针域和一个数据域。一个是孩子指针域,另一个是兄弟指针域!只要是当前节点的孩子就挂到孩子节点后面,如果是兄弟节点则挂到兄弟节点的后面,这样就可以把非二叉树转换为二叉树来处理了!

typedef char DataType;
struct Node
{
	struct Node* _LeftChild;
	struct Node* _RightBother;
	DataType _data;
};

树结构在现实中的应用

树这种结构其实在现实中应用的地方不多,最典型的就是文件系统的目录结构!

这就是Linux下的一个文件目录系统结构,他就是一棵多叉树!

二、二叉树的概念和结构

二叉树的概念

二叉树:至多为2的树,被称为二叉树!

注意:这里是至多,也就是说度可以为0,1 ,  2都可以!

二叉树是由一个根节点和左右子树构成的!

二叉树有左右之分!次序不能颠倒!

二叉树的5种特殊情况:

所有的二叉树都是由以上5中组成的!

特殊的二叉树

满二叉树:一个二叉树,如果每一层的节点数都达到最大值,则称该二叉树为满二叉树!(也就是说如果一个二叉树有K层它的节点总数是:2^k  - 1就说明他是满二叉树)

完全二叉树:对于深度为K,节点数是n的二叉树,当且仅当每一个节点与深度为K的那一层的每一个编号都对应(也就是说前K-1层是满的,第K层按序号依次存放的)的树被称为完全二叉树!也就是说满二叉树实际上是完全二叉树的特例

OK,画个图理解一下:

完全二叉树是很有用的!后面我们玩的堆、堆排序、TopK问题都是基于完全二叉树实现的!

二叉树的性质

(1)若规定根节点的层数为1,则一棵非空二叉树的第i层上最多有2^(i-1)个节点

(2)若规定根节点的层数为1,则一棵高度为h的二叉树的最大节点数是2^(h) - 1

(3)若规定根节点的层数为1,则具有n个节点的满二叉树的深度h = log2(N+1)

(4)对于任意一棵二叉树,假设度为0的节点(叶子结点)的个数为n0,度为2的节点的个数为n2,则有n0 = n2 + 1

(5)对于高度为h的二叉树的节点范围[2^(h-1), 2^(h)-1]

(6)对于具有n个结点的完全二叉树,如果按照从上至下从左至右的数组顺序对所有节点从0开始编号,则对于序号为i的结点有:

若i > 0,位置节点的双亲下标为:(i-1)/2,根节点无双亲

若2i+1 < n, 则左孩子的下标为2i+1,否则如果2i+1 >= n则无左孩子

若2i+1 < n, 则右孩子的下标为2i+2,否则如果2i+2 >= n则无右孩子

二叉树的存储

二叉树的存储一般分为:顺序存储链式存储两种~!

1、顺序存储

顺序存储就是用数组来存储一般的二叉树都是不适合用数组存的,因为会有空间的浪费,只有完全二叉树才适合用数组来存储!堆就是这样搞的(后面会介绍)!二叉树用数组存储(顺序存储)在物理上是一个数组,在逻辑上是一棵二叉树!

2、链式存储

二叉树的链式存储是指,用链表表示(存储)一棵二叉树,也就是用链表来指示各个节点的逻辑关系!一般每个节点都有三个域,一个数据域,两个指针域(左右指针域),它两分别指向二叉树的左右节点。链式存储又可以分为二叉链和三叉链,我们这里玩的是二叉链,三叉连后期在介绍,他是玩那个红黑树的!

typedef char BTDataType;
typedef struct BinaryTreeNode
{
	BTDataType datal;
	struct BinaryTreeNode* left;
	struct BinaryTreeNode* right;
}BT;

OK,本期二叉树的基础知识就介绍到这里,我们下期再来对顺序存储和链式存储来实现!

猜你喜欢

转载自blog.csdn.net/m0_75256358/article/details/134383515
今日推荐