1.树的介绍
1.1树的概念
树是一种数据结构,由n(n>=1)个有限结点组成的一个具有层次关系的集合。每颗树都有一个根结点,根结点下有若干个子结点,每一个非根结点有且只有一个父结点(根节点没有父结点)。
简单来看,树的结构如下图

- 节点的度:一个节点含有的子树的个数称为该节点的度; 如上图:A的为2
- 叶节点:度为0的节点称为叶节点; 如上图:G、H、I节点为叶节点
- 兄弟节点:具有相同父节点的节点互称为兄弟节点; 如上图:B、C是兄弟节点
- 树的度:一棵树中,最大的节点的度称为树的度; 如上图:树的度为2
- 节点的层次:从根开始定义起,根为第1层,根的子节点为第2层,以此类推;
- 节点的祖先:从根到该节点所经分支上的所有节点;如上图:A是所有节点的祖先
- 子孙:以某节点为根的子树中任一节点都称为该节点的子孙。如上图:所有节点都是A的子孙
- 森林:由m棵互不相交的树的集合称为森林;
1.2树的实现
孩子兄弟表示法:每个结点有两个指针,分别指向孩子和兄弟,若没有则指向NULL。
例如:A的pC(pChild)指针只指向他的第一个孩子B,pB(pBrother)指针指向NULL。
进入到下一层,B的pC指向D,pB指向C。C的pC指向G,pB指向空,以此类推。

2.二叉树的介绍
2.1概念
一棵二叉树是结点的一个有限集合,该集合或者为空,或者是由一个根节点加上两棵别称为左子树和右子树的二叉树组成。
二叉树的特点:
- 每个结点最多有两棵子树,即二叉树不存在度大于2的结点。
- 二叉树的子树有左右之分,其子树的次序不能颠倒。


2.2特殊的二叉树

这里要提一下,完全二叉树的最后一层不满,但从左到右是连续的 



2.3二叉树的实现(手动连接版)
typedef char BTDataType;
typedef struct BinaryTreeNode
{
BTDataType data;
BTNode* left;
BTNode* right;
}BTNode;
int main()
{
BTNode a;
a.data = 'A';
BTNode b;
b.data = 'B';
BTNode c;
c.data = 'C';
BTNode d;
d.data = 'D';
BTNode e;
e.data = 'E';
a.left = &b;
a.right = &c;
c.left = NULL;
c.right = NULL;
b.left = &d;
b.right = &e;
d.left = NULL;
d.right = NULL;
e.left = NULL;
e.right = NULL;
return 0;
}

2.4遍历二叉树
首先,可以将任何一颗二叉树分为三个部分
1.根节点
2.左子树
3.右子树
所以遍历的时候可以采用分治算法,分而治之,将大问题分成相同类型的子问题,子问题再分,直到不可分为止。
1.深度优先遍历
也叫前中后序优先遍历
遍历方法为递归,递归思路有以下三种
前序(先根):根,左子树,右子树
A,B,D,NULL,NULL,E,NULL,NULL,C,NULL,NULL
中序(中根):左子树,根,右子树(访问一棵树的时候,要先访问这颗树的左子树,再根,再右子树)
NULL,D,NULL,B,NULL,E,NULL,A,NULL,C,NULL
后序(后根):左子树,右子树,根
NULL,NULL,D,NULL,NULL,E,B,NULL,NULL,C,A

void PreOrder(BTNode* root)//前序
{
if (root == NULL)
{
return;
}
printf("%c ", root->data);
PreOrder(root->left);
PreOrder(root->right);
}
void InOrder(BTNode* root)//中序
{
if (root == NULL)
{
return;
}
InOrder(root->left);
printf("%c ", root->data);
InOrder(root->right);
}
void PostOrder(BTNode* root)//后序
{
if (root == NULL)
{
return;
}
PostOrder(root->left);
PostOrder(root->right);
printf("%c ", root->data);
}
2.广度优先遍历
也叫层序优先遍历
1)将A入队列

(2)判断队列是否为空,不为空就将A出队列,再将A的”孩子“入队列。

(3)判空,将B出队列,将B的“孩子”入队列。

(4)判空,将C出队列,将C的“孩子”入队列。

(5)判空,将D出队列,将D的“孩子”入队列(“孩子”为空则不进队列)

。。。。。。。。(步骤同理)

(6)最后,队列为空结束遍历。
2.5二叉树一些基本功能的实现
计算二叉树的大小
void TreeSize(BTNode* root, int* psize)//函数用传址的psize来记录树的大小
{ //但函数实际上实现的是遍历一棵树的根,左子树,右子树
if (root == NULL) //判断当前节点是否为空,来决定是否psize++
{
return;
}
else
{
(*psize)++;
}
TreeSize(root->left);
TreeSize(root->right);
}
或
int TreeSize(BTNode* root)
{
return root == NULL ? 0 : TreeSize(root->left) + TreeSize(root->left) + 1;
}
//函数的功能是算出一棵树的大小
//若根不为空,则返回根加上左子树的大小加上右子树的大小
计算二叉树 叶子结点的个数
int TreeLeafSize(BTNode* root)//这个函数的功能是算出叶子结点的个数
{
if (root == NULL)
{
return 0;
}
if (root->left == NULL && root->right == NULL)
{
return 1;
}
return TreeSize(root->left)+ TreeSize(root->right);
//除上面两种特殊请况外,算出左子树的叶子+右子树的叶子,即树的叶子
}
销毁二叉树

文章介绍了树作为一种数据结构的基本概念,包括根节点、度、叶节点等概念,并展示了孩子兄弟表示法来实现树结构。接着,文章详细讲解了二叉树的定义,特点以及特殊的完全二叉树。在二叉树的实现部分,通过代码展示了手动创建二叉树的过程。此外,文章还阐述了二叉树的两种遍历方法——深度优先遍历(前序、中序、后序)和广度优先遍历,并提供了相应的遍历函数。最后,提到了计算二叉树大小、叶子节点数量以及销毁二叉树等基本操作。

5202

被折叠的 条评论
为什么被折叠?



