前言
在生活中有很多关于树和二叉树的例子,我们对文件进行操作的时候,文件系统就是利用了目录树结构而实现的。今天我们来学习树和二叉树的概率以及实现。
目录
树的概念及结构
树的概念
树是一种非线性
的数据结构,它是由
n
(
n>=0
)个有限结点组成一个具有层次关系的集合。把它
叫做树是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。
树有一个特殊的结点,称为根结点,根节点没有前驱结点
除根节点外,其余结点被分成M(M>0)
个互不相交的集合
T1
、
T2
、
……
、
Tm,其中每一个集
合Ti(1<= i <= m)又是一棵结构与树类似的子树。每棵子树的根结点有且只有一个前驱,可以
有0个或多个后继
因此,树是递归定义的。
![](https://i-blog.csdnimg.cn/direct/a967c877dc284d688d054d78fa73c2eb.png)
重要!!!
节点的度:一个节点含有的子树的个数称为该节点的度; 如上图:A
的为2,B的为3.
叶节点或终端节点:度为0
的节点称为叶节点; 如上图:D E F G
等节点为叶节点
非终端节点或分支节点:度不为0
的节点; 如上图:B C
节点为分支节点
双亲节点或父节点:若一个节点含有子节点,则这个节点称为其子节点的父节点; 如上图:A
是B
的父节点
孩子节点或子节点:一个节点含有的子树的根节点称为该节点的子节点; 如上图:B
是
A的孩子节
点
兄弟节点:具有相同父节点的节点互称为兄弟节点; 如上图:B
、
C是兄弟节点
树的度:一棵树中,最大的节点的度称为树的度; 如上图:树的度为3
节点的层次:从根开始定义起,根为第1
层,根的子节点为第
2层,以此类推;
树的高度或深度:树中节点的最大层次; 如上图:树的高度为3
节点的祖先:从根到该节点所经分支上的所有节点;如上图:A是所有节点的祖先
子孙:以某节点为根的子树中任一节点都称为该节点的子孙。如上图:所有节点都是A的子孙
森林:由m
(
m>0)棵互不相交的多颗树的集合称为森林;(数据结构中的学习并查集本质就是
一个森林)
树的结构表示
树结构相对线性表就比较复杂了,要存储表示起来就比较麻烦了,实际中树有很多种表示方式,
如:双亲表示法,孩子表示法、孩子兄弟表示法等等。我们这里就简单的了解其中最常用的孩子
兄弟表示法
typedef int NodeDate;
struct Node
{
struct Node* FirstChild1;//第一个孩子结点
struct Node* NextBrother;//指向其下一个兄弟结点
NodeDate val; //节点中的数据
};
下面是兄弟表示法的具体流程,当知道第一个孩子结点,将这个孩子指向他的下一个兄弟结点,这样树的整体结构就能够串联起来。
二叉树的概念及结构
二叉树的概念
一棵二叉树是结点的一个有限集合,该集合或者为空,或者是由一个根节点加上两棵别称为左子
树和右子树的二叉树组成。
二叉树的特点:
1. 每个结点最多有两棵子树,即二叉树不存在度大于2的结点。
2. 二叉树的子树有左右之分,其子树的次序不能颠倒。
二叉树链式结构的实现
二叉树链式结构的遍历
所谓遍历
(Traversal)
是指沿着某条搜索路线,依次对树中每个结点均做一次且仅做一次访问。访
问结点所做的操作依赖于具体的应用问 题。 遍历是二叉树上最重要的运算之一,是二叉树上进行
其它运算之基础。
前序/中序/后序的递归结构遍历:是根据访问结点操作发生位置命名
1. NLR:前序遍历(Preorder Traversal 亦称先序遍历)——访问根结点的操作发生在遍历其左右
子树之前。
2. LNR:中序遍历(Inorder Traversal)——访问根结点的操作发生在遍历其左右子树之中
(间)。
3. LRN:后序遍历(Postorder Traversal)——访问根结点的操作发生在遍历其左右子树之后。
由于被访问的结点必是某子树的根,所以N(Node)、L(Left subtree)和R(Right subtree)又
可解释为根、根的左子树和根的右子树。NLR、LNR和LRN分别又称为先根遍历、中根遍历和后根
遍历
前序遍历的实现
前序遍历的遍历顺序是,根->左子树->右子树。
从图中可以看出最后遍历出数据的顺序是A B D G H C E I F。
仔细观察可以发现,这种图类似与递归算法。所以在实现二叉树的遍历时可以用递归算法来实现。
void PrevOrder(BTNode* root)
{
if (root == NULL)
{
printf("NULL");
return;
}
printf("%d", root->val);
PrevOrder(root->Left);
PrevOrder(root->Right);
}
中序遍历的实现
中序遍历的遍历顺序是,左子树->根->右子树。
从图中可以看出最后遍历出数据的顺序是G D H B A E I C F。
同样我们利用递归算法来实现它。
void InOrder(BTNode* root)
{
if (root == NULL)
{
printf("NULL");
return;
}
InOrder(root->Left);
printf("%d", root->val);
InOrder(root->Right);
}
后序遍历的实现
中序遍历的遍历顺序是,左子树->右子树>根。
从图中可以看出最后遍历出数据的顺序是G H D B A I E F C 。
同样我们利用递归算法来实现它。
void PostOrder(BTNode* root)
{
if (root == NULL)
{
printf("NULL");
return;
}
PostOrder(root->Left);
PostOrder(root->Right);
printf("%d", root->val);
}
好啦,这就是今天学习的分享啦!看到希望大家的三连呀!
如果有不当之处,欢迎大佬指正!