本节是树的一些知识,为了防止忘记,写个帖子记录!
这是B站郝斌老师的视频写笔记整理;
定义:
- 专业定义:
-
有且只有一个成为根的结点
-
有若干个互不相交的子树,这些子树本身也是一棵树
-
通俗的定义:
树是由结点和边组成
每个节点只有一个父节点,但可以有多个子节点
但有一个结点例外,该节点没有父节点,此节点称为根节点 -
专业术语:
结点、父节点、子节点、根节点、
子孙 、堂兄弟
深度:从根节点到最底层结点的层数称之为深度;其中,根节点是第一层;
叶子节点:没有子节点的结点
非终端结点:实际就是非叶子节点
度:子节点的个数称为度
分类:
-
一般树:任意一个结点的子节点个数都不受限制
-
二叉树:任意一个节点的子节点个数做多为两个,且子节点的位置不可更改
- 分类:
一般二叉树:。。。。。。
满二叉树:在不增加树的层数的前提下,无法再多添加一个结点的二叉树就是满二叉树。
完全二叉树:如果只是删除了满二叉树最底层最右面的连续若干个节点,这样形成的二叉树,就是完全二叉树。
- 分类:
-
森林:N个互不相交的树的集合
存储:
-
二叉树的存储
-
连续存储[完全二叉树]
优点:查找某个结点的父节点和子节点(也包括判断有没有子节点)速度快
缺点:占用内存较大
-
链式存储
-
-
一般树的存储
-
双亲表示法
-
孩子表示法
-
双亲孩子表示法
-
-
二叉树表示法
把一个普通树转化为二叉树了来存储,具体转换方法是:
设法保证任意一个结点的左指针域指向他的第一个孩子,右指针域指向他的兄弟
只要满足此条件就可以把一个普通树转化为二叉树:一个普通的树转换成的二叉树一定没有右子树。
-
森林的存储
先把森林转化为二叉树,再存储二叉树;把这几个的根节点当成是兄弟结点右指针指向兄弟结点,左指针指向子节点。多个树,把g
操作:
-
树的遍历
-
先序遍历
先访问根节点
再先序访问左子树
再先序访问右子树
-
中序遍历
中序遍历左子树
再访问根节点
再中序遍历右子树
-
后序遍历
后序遍历左子树
后序遍历右子树
访问根节点
【常考重点】已知两种遍历序列求原始二叉树
示例1:
先序:ABCDEFGH
中序:BDCEAFHG
求后序:DECBHGFA
示例2:
先序:ABDGHCEFI
中序:GDHBAECIF
求后序:DECBHGFA
-
应用:
- 树是数据库中数据组织一种重要形式
- 操作系统父子进程的关系本身就是一种树
- 面向对象中类的继承关系本身就是一棵树
- 赫夫曼树
链式二叉树遍历程序
#include <stdio.h>
#include <malloc.h>
typedef struct BiTree
{
char data;
struct BiTree * pLBiTree;
struct BiTree * pRBiTree;
}BiTree, *pBiTree;
pBiTree create_BiTree(void);
void Create_BinTree(pBiTree T);
void pre_traserse(pBiTree pB);
void middle_traserse(pBiTree pB);
void post_traserse(pBiTree pB);
int main(void)
{
pBiTree BTree;
BTree = create_BiTree();
pre_traserse(BTree);
printf("\n");
middle_traserse(BTree);
printf("\n");
post_traserse(BTree);
printf("\n");
return 0;
}
pBiTree create_BiTree(void)
{
pBiTree pA = (pBiTree)malloc(sizeof(BiTree));
pBiTree pB = (pBiTree)malloc(sizeof(BiTree));
pBiTree pC = (pBiTree)malloc(sizeof(BiTree));
pBiTree pD = (pBiTree)malloc(sizeof(BiTree));
pBiTree pE = (pBiTree)malloc(sizeof(BiTree));
pBiTree pF = (pBiTree)malloc(sizeof(BiTree));
pBiTree pG = (pBiTree)malloc(sizeof(BiTree));
pA->data = 'A';
pB->data = 'B';
pC->data = 'C';
pD->data = 'D';
pE->data = 'E';
pF->data = 'F';
pG->data = 'G';
pA->pLBiTree = pB;
pA->pRBiTree = pC;
pB->pLBiTree = pD;
pC->pLBiTree = pE;
pC->pRBiTree = pF;
pF->pLBiTree = pG;
pB->pRBiTree = NULL;
pD->pLBiTree = pD->pRBiTree = NULL;
pE->pLBiTree = pE->pRBiTree = NULL;
pG->pLBiTree = pG->pRBiTree = NULL;
pF->pRBiTree = NULL;
return pA;
}
void pre_traserse(pBiTree pB)
{
if(NULL != pB)
{
printf("%c ",pB->data);
if(NULL != pB->pLBiTree)
pre_traserse(pB->pLBiTree);
if(NULL != pB->pRBiTree)
pre_traserse(pB->pRBiTree);
}
}
void middle_traserse(pBiTree pB)
{
if(NULL != pB)
{
if(NULL != pB->pLBiTree)
middle_traserse(pB->pLBiTree);
printf("%c ",pB->data);
if(NULL != pB->pRBiTree)
middle_traserse(pB->pRBiTree);
}
}
void post_traserse(pBiTree pB)
{
if(NULL != pB)
{
if(NULL != pB->pLBiTree)
post_traserse(pB->pLBiTree);
if(NULL != pB->pRBiTree)
post_traserse(pB->pRBiTree);
printf("%c ",pB->data);
}
}