树的定义及相关概念
来源:互联网 发布:800源码 编辑:程序博客网 时间:2024/04/28 21:38
树的定义与表示法
树(Tree)是n(n≥0)个结点的有限集T,T为空时称为空树,否则它满足如下两个条件:
① 有且仅有一个特定的称为根(Root)的结点; ② 其余的结点可分为m(m≥0)个互不相交的子集T1,T2,…,Tm,其中每个子集本身又是一棵树,并称其为根的子树(Subtree)。
树的递归定义刻化了树的固有特性,即一棵非空树是由若干棵子树构成的,而子树又可由若干棵更小的子树构成。
从该定义可知:只有一个结点的树,该结点为根结点;多个结点的树,除根结点之外,它的M棵子树T1,T2,…,Tm也是树,且互不相交。
树的表示法
树形表示法
嵌套集合表示法
凹入表表示法
广义表表示法 树的有关术语
度(Degree):
一个结点拥有的子树数称为该结点的度。
树的度:一棵树的度是指该树中结点的最大度数。
叶子(Leaf)和分支结点:
度为零的结点称为叶子或终端结点。
度不为零的结点称为分支结点或非终端结点。
除根结点之外的分支结点统称为内部结点,
根结点又称为开始结点。
双亲(Parents)和孩子(Child):
树中某个结点的子树之根称为该结点
的孩子或儿子,相应地,该结点称为孩子的双亲或父亲。
兄弟(Sibling)和堂兄弟:
同一个双亲的孩子称为兄弟。
双亲在同一层的结点互为堂兄弟。
路径(Path):若树中存在一个结点序列
k1,k2,…,kj,使得kj是ki+1的双亲
(1≤i<j),则称该结点序列是从
ki到kj的一条路径或道路。
若一个结点序列是路径,则在树的树形图表示中,该结点序列“自上而下”地通过路径上的每条边。
祖先(Ancestor)和子孙(Descendant):
一个结点的祖先是指从树的根到该结点所经
分枝上的所有结点(包括根结点)。一个结点的子树的所有结点都称为该结点的子孙。
结点的层数(Level):
是从根起算,设根的层数为1,
其余结点的层数等于其双亲结点
的层数加1。
树的高度(Height):
树中结点的最大层数称
为树的高度或深度(Depth)。
有序树(Ordered Tree)
和无序树(Unordered Tree):
若将树中每个结点的各子树看成
是从左到右有次序的(即不能互换),
则称该树为有序树;否则称为无序树。
森林(Forest):是m(m≥0)棵互不相交
的树的集合。
对树中每个结点而言,其子树的集合即为森林;反之,给一个森林加上一个结点,使原森林的各棵树成为所加结点的子树,便得到一棵树。
6.2 二叉树的定义
二叉树的定义
二叉树(Binary Tree)是n(n≥0)个结点的有限集,它或者是空集(n=0),或者由一个根结点及两棵互不相交的、分别称作这个根的左子树和右子树的二叉树组成。
若二叉树为空集,则称为空二叉树。
二叉树是有序的,它的每个结点至多只有两棵子树,
且有左、右之分,不能互换;
左右子树也可以是空二叉树。
二叉树的基本形态
空二叉树
仅有根结点的二叉树
右子树为空的二叉树
左子树为空的二叉树
左右子树均非空的二叉树
树与二叉树的区别
树至少包含一个称为根的结点,而二叉树可以是空二叉树;
树的结点可有任意有限棵子树(直接后续),而二叉树的任一结点至多只有两棵子树(直接后续);
树中各子树可以不必区分各子树之间的次序(但有序树规定了左、右排列次序),而二叉树中将两棵子树明确地区分为左子树和右子树,并且当二叉树中一棵子树为空、另一棵子树为非空时,也要明确地指出它们的左、右次序。
二叉树是有序的,它的每个结点至
多只有两棵子树,且有左、右之分,
不能互换;
左右子树也可以是空二叉树。
6.2.2 二叉树的性质
二叉树的特殊形态
满二叉树(Full Binary Tree):一棵深度为k且有2k-1个结点的二叉树。
特点1:二叉树的所有分支结点都存在
左子树和右子树
特点2:二叉树的所有叶子结点都在同一层上
完全二叉树(Complete Binary Tree):深度为k的,有n个结点的二叉树,当且仅当其每一个结点都与深度为k的满二叉树中编号从1至n的结点一一对应。
将满二叉树删除一些结点得到
从右下角开始,从右到左,从
下到上,删除一些结点
二叉树的性质
性质1: 在二叉树的第i层上至多有2^(i-1)个结点
(i≥1)。
性质2: 深度为k的二叉树至多有2^k-1个结点
(k≥1)。
性质3: 对任何一棵二叉树T,
如果其终端叶子结点数为n0,
度为2的结点数为n2,则
n0=n2+1
性质4: 具有n个结点的完全二叉树的
深度为「log2n」+1
性质5: 如果对一棵有n个结点的完全二叉树
按层序编号(从第1层,每层从左到右,从上到下),
则对任一结点i
(1≤i≤n),有
如果 i=1,则结点i是二叉树的根,无双亲;
如果 i>1,则其双亲PARENT(i)是结点「i/2」。
如果2i>n,则结点i无左孩子(结点i为叶子结点);否则其左孩子LCHILD(i)是结点2i。
如果2i+1>n,则结点i无右孩子;否则其右孩子RCHILD(i)是结点2i+1。
typedef char DataType;
typedef struct node{
DataType data;
struct node *lchild, *rchild;
}BinTNode;
typedef BinTNode *BinTree;
void main(){
/*空二叉树,只有指向树根的指针变量,
没有任何结点。*/
BinTree Tree=NULL;
CreateBinTree(...);
PreOrder(Tree); Tree是指向树根结点的指针
}
void PreOrder(BinTree T){
if(T){
printf("%c",T->data);
PreOrder(T->lchild);
PreOrder(T->rchild);
}
}
6.3 二叉树的遍历
二叉树遍历的基本概念
遍历(Traversal):
依次对树中每个结点均做一次且仅做一次访问。
分别称之为前序遍历,中序遍历和后序遍历。
前序遍历
前序遍历(Preorder Traversal)亦称先序遍历,
定义为:
若二叉树为空,则空操作;
否则,执行下列步骤:
(1)访问根结点
(2)前序遍历左子树
(3)前序遍历右子树
a abdche
/ /
b c
/ / /
d h e
(1)访问根结点 a
(2)前序遍历左子树(以b为根)
(1)访问根结点 b
(2)前序遍历左子树 d
(3)前序遍历右子树
(3)前序遍历右子树(以c为根)
(1)访问根结点 c
(2)前序遍历左子树 h
(3)前序遍历右子树 e
a
/ /
b c
/ / / /
d ! h e
/ / / / / /
! ! ! ! ! !
abd!!!ch!!e!!
(1)访问根结点 a a
(2)前序遍历左子树 b根
(1)访问根结点 b b
(2)前序遍历左子树 d d
(3)前序遍历右子树 ^
(3)前序遍历右子树 c根
(1)访问根结点 c c
(2)前序遍历左子树 h h
(3)前序遍历右子树 e e
a 前序:abdqxkLmchewy
/ / 中序:dqbkxmlahcwey
b c 后序:qdkmlxbhwyeca
/ / / /
d x h e
/ / / / /
q k L w y
/
m
a 前序:abdqxklmchewy
/ / 中序:dqbkxmlahcwey
b c 后序:qdkmlxbhwyeca
/ / / /
d x h e
/ / / / / / / /
! q k L ! ! w y
/ / // / / / / / /
! ! ! ! m ! ! ! ! !
/ /
! !
前序:abd!q!!xk!!lm!!!ch!!ew!!y!!
(1)访问根结点 a
(2)前序遍历左子树 以b为根
(1)访问根结点 b
(2)前序遍历左子树 d
(3)前序遍历右子树 ^
(3)前序遍历右子树 以c为根
(1)访问根结点 c
(2)前序遍历左子树 以h为根
(1)访问根结点 h
(2)前序遍历左子树 以k为根 k
(3)前序遍历右子树 以L为根
(1)访问根结点 L
(2)前序遍历左子树 以m为根 m
(3)前序遍历右子树 ^
(3)前序遍历右子树 以e为根 e
中序遍历
中序遍历(Inorder Traversal)定义为:
若二叉树为空,则空操作;
否则,执行下列步骤:
(1)遍历左子树
(2)访问根结点
(3)遍历右子树
a
/ /
b c
/ / /
d h e
dbahce
后序遍历
后序遍历(Postorder Traversal)定义为:
若二叉树为空,则空操作;否则,执行下列步骤:
(1)遍历左子树
(2)遍历右子树
(3)访问根结点
a
/ /
b c
/ / /
d h e
dbheca
构造二叉链表
基于先序遍历构造二叉链表算法。
度(Degree):一个结点拥有的子树数称为该结点的度。
a 前序:abdqxklmchewy
/ / 中序:dqbkxmlahcwey
b c 后序:qdkmlxbhwyeca
/ / / /
d x h e
/ / / / /
q k L w y
/
m
简单递归程序写法
1、写出递归函数的定义:
函数名,参数,结果(返回值类型和意义)
2、处理边界情况
3、按照递归函数的定义
(利用低一级结果,得到本级的结果),
自己调用自己,自圆其说
1、递归函数的定义:
名字:PreOrder,
参数T:树根结点的地址
结果:打印前序遍历
2、处理边界情况 : 空树,无打印
if(T==NULL)return;
3、不是空树
printf("%c",T->data); 打印根
PreOrder(T->lchild); 前序打印左子树
PreOrder(T->rchild); 前序打印右子树
+---------
整个树的前序
}
}
a a b !! c !!
/ /
b c
/ / / /
! ! ! !
a a ! b ! !
/ /
! b
/ /
! !
a ab!!!
/ /
b !
/ /
! !
a a!!hjgfhjhj
/ /
! !
递归程序写法
1、写出递归函数的定义:
函数名,参数,结果(返回值类型和意义)
2、处理边界情况 if(T=NULL) {return 0;printf("你……");}
3、按照递归函数的定义
(利用低一级结果,得到本级的结果),
自己调用自己,自圆其说 ——自圆其说是如何编写调用程序代码,最难在这里~
1、写出递归函数的定义:
函数名Height
参数:T=树根结点的地址
结果:计算树的高度
2、处理边界情况:树空
if(T==NULL)return 0;
/*边界情况:如果是空树,高度0 */
3、按照递归函数的定义
(利用低一级结果,得到本级的结果),
自己调用自己,自圆其说
树不空
左子树高度Height(T->lchild)
右子树高度Height(T->rchild)
整个树的高度=max(左子树高度,右子树高度)+1
int Height(BinTree T){
int h1,h2;
/*t是指向根的指针变量
函数定义:计算t为根的二叉树高度*/
if(T==NULL)return 0;/*边界情况:如果是空树,高度0 */
h1=Height(T->lchild);
h2=Height(T->rchild);
if(h1>h2)return h1+1;
else return h2+1;
/*自圆其说:max{左子树高度,右子树高度}+1*/
}
递归程序写法
1、写出递归函数的定义:
函数名:NodeCount
参数:T=树根结点的地址
结果:计算树的结点数
2、处理边界情况:空树
if(T==NULL)return 0;
3、按照递归函数的定义
(利用低一级结果,得到本级的结果),
自己调用自己,自圆其说
不是空树
左子树结点数NodeCount(T->lchild)
右子树结点数NodeCount(T->rchild)
整个树的结点数=左子树结点数+右子树结点数+1
int NodeCount(BinTree T){
/*t是指向根的指针变量
函数定义:计算t为根的二叉树结点数 */
if(T==NULL)return 0;
/*边界情况:如果是空树,结点数为0*/
return NodeCount(T->lchild)+NodeCount(T->rchild)+1;
/*自圆其说:左子树结点数+右子树结点数+根数1*/
}
递归程序写法
1、写出递归函数的定义:
函数名:LeafCount
参数:T=树根结点的地址
结果:计算树的叶子数
2、处理边界情况:空树,只有根
if(T==NULL)return 0;
if(T->lchild==NULL&&T->rchild==NULL)
return 1;
3、按照递归函数的定义
(利用低一级结果,得到本级的结果),
自己调用自己,自圆其说
不是空树
左子树叶子数LeafCount(T->lchild)
右子树叶子数LeafCount(T->rchild)
整个树的叶子数=左子树叶子数+右子树叶子数
int LeafCount(BinTree T){
/*t是指向根的指针变量
函数定义:计算t为根的二叉树叶子结点数*/
if(T==NULL)return 0;
/*边界情况:如果是空树,结点数为0*/
if(T->lchild==NULL&&T->rchild==NULL)return 1;
/*边界情况:如果只有根,叶子结点数为1*/
return LeafCount(T->lchild)+LeafCount(T->rchild);
/*自圆其说:叶子结点数=左子树叶子结点数+右子树结点数*/
}
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/SinQiay/archive/2009/05/16/4193611.aspx
- 树的定义及相关概念
- 树的定义和相关概念
- 二叉树的定义及其相关概念
- 子网掩码相关的概念定义
- 二叉树的相关概念及性质
- 电子商务的概念及定义
- 数据结构中树的基本定义相关概念汇总
- 树的定义及相关术语
- UI测试的定义和相关概念
- Protege4学习笔记(一)---本体定义及相关概念
- 树的相关概念
- 树的相关概念
- 树的相关概念
- 【基础算法】(11)树的概念及相关算法(一)
- 树的相关定义
- PWM控制的基本原理及相关概念
- xml的相关概念及注意事项
- 包的定义及相关注意事项
- 鲜花慢慢开
- 海阔天空
- eclipse + JBoss 5 + EJB3开发指南(4):Session Bean中的注释方法
- eclipse + JBoss 5 + EJB3开发指南(5):使用配置文件发布Session Be
- C与C++《精通Unix下C语言与项目实践》读书笔记(8)
- 树的定义及相关概念
- 开心
- Head First JavaScript中文版已打成pdf,欢迎下载
- 中央电视台著名播音员罗京今日7时05分病逝
- 使用委托作为参数进行动态调用
- 鲜花慢慢开
- 第一次
- 一个失败的程序,希望大家指点
- 加入浩为