目录
一、树的基本概念
1.有且仅有一个根节点
2.没有后继的结点称为“叶子结点”(或终端结点)
3.有后继的结点称为“分支结点”(或非终端结点)
4.除了根节点外,任何一个结点都且仅有一个前驱
5.每个结点可以有0个或多个后继
1.有且仅有一个特定的称为根的结点
2.当n>1的时候,其余结点可分为m(m>0)个互不相干的有限集合T1,T2...Tm,其中每个集合本身又是一颗树,并且称为
根结点的子树。
二、结点之间的关系描述
上图中,“你”结点的祖先结点有“父亲”,“爷爷”
“M”结点的祖先结点有“H”,“三叔”,“爷爷”
上图中,“父亲”结点的子孙结点有“你”,“K”,“L”和“F”
上图中,“你”的双亲结点是“父亲”
上图中,“你”结点,“F”结点都是“父亲”结点的孩子结点
上图中,“父亲”结点,“二叔”结点和“三叔”结点之间是兄弟的关系,所有可以说“二叔”结点是“父亲”结点的
兄弟结点
三、结点、树的属性描述
“爷爷”结点位于第一层,“父亲”,“二叔”和“三叔”位于第二层...
“K”,“L”和“M”三个结点的高度都是为1;....;“父亲”,“二叔”和“三叔”三个结点的高度都是3...
上图中,树的高度为4
上图中,“父亲”结点有两个分支,所以它的度为2;“二叔”结点有一个分支,所以它的度为1;“K”结点没有分支,所以它的度为0
上图中,“三叔”结点的分支最多为3,所有树的度为3
四、有序树,无序树和森林
五、树的常考性质
比如“A”结点的度数为3(3相当于第2层的结点个数);“B”结点的度数为2,“C”结点的度数为1,“D”结点的度数为3,那么2+1+3=6(相当于是第3层的结点个数);“E”结点的度数为2,“H”结点的度数为1,那么2+1=3(相当于是第4层的结点个数)
各结点的总度数=第2层结点数+第3层结点数+....
所以结点数=总度数+1
树的度--各结点的度的最大值;m叉树--每个结点最多只能有m个孩子的树
m叉树第i层至多有m^(i-1)个结点
分析:高度为h---意味着该树有h层;m叉树---意味着每个结点最多只能有m个孩子
计算该树最多的结点数目的时候:第1层有m^0=1个结点;第2层有m个结点,第3层:第2层的第1个结点有m个结点(对应第3层有m个结点),第3层的第2个结点有m个结点(对应第3层有m个结点)+.....,一共有m个m,也就是m^2,所以第3层有m^2个结点;第4层有m^2个m的结点,也就是m^3个结点.....第n=h层有m^(h-1)个结点。
最多的结点数:1+m+m^2+....+m^(h-1)=(1-m^h)/(1-m)
对于第一种:可以让第1层到第h层都是1个结点。
对于第二种:度为m---意味着有一个结点必须有m个孩子,那么可以让第1层到第h-1层都是一个结点,第h层有m个结点此时共有h-1+m个结点
六、树的遍历
1.访问根结点;2.按照从左到右的次序先根遍历根结点的每一棵子树
上图先根遍历得到:A BEF CGJ DH IKLM
1.按照从左到右的次序后根遍历根结点的每一棵子树;2.访问根结点
上图后根遍历得到:EFB JGC H KLMID A
1.访问第1层的结点(根结点);2.按照从左到右的次序依次访问第2层....,第h层的结点
上图层次遍历得到:ABCDEFGHIJKLM
七、树的存储结构
用一维数组来存放一棵树的所有结点,每个结点除了存放本身信息外,还要存放其双亲在
数组中的位置。
每个结点有两个域:
data——存放结点信息
parent——存放该结点双亲在数组中的位置
特点:求某个结点的双亲结点十分容易
- #define MAXSIZE 100
- #define char ElemType
- typedef struct PTreeNode
- {
- ElemType data;
- int parent;//双亲指示器,指示结点的双亲在数组中的位置
- }PTreeNode;
-
- typedef struct PTree
- {
- PTreeNode nodes[MAXSIZE];
- int r, n;//r表示根结点在数组中的位置,n表示树中结点总数
- }PTree;
每个结点的孩子用单链表存储。
n个结点可以有n个孩子链表(叶子结点的孩子链表为空表)
n个孩子链表的头指针用一个向量表示。
特点:求某个结点的孩子容易,求双亲难
- #define char ElemType
- #define MAXSIZE 20
- typedef struct CTNode
- {
- int child;//child域存放结点在一维数组中的位置
- struct CTNode* next;
- }*ChildPtr;//ChildPtr指向孩子结点的指针
-
- typedef struct
- {
- ElemType data;//data域存放结点本身的信息
- ChildPtr firstchild;//firstchild域存放第一个孩子的指针
- }CTBox;
-
- typedef struct
- {
- CTBox nodes[MAXSIZE];
- int n, r;//n表示树的结点数,r存放根结点的位置
- }CTree;
每个结点的左链域指向该结点的第一个孩子,右链域指向下一个兄弟结点
特点:可以方便的实现树和二叉树的相互转换
- typedef struct CSNode
- {
- ElemType data;
- struct CSNode* vp;//指向孩子结点的指针
- struct CSNode* hp;//指向兄弟的指针
- }CSNode;