树的定义:树是n(n>=0)个结点的有限集,n为零时为空树。在非空树中,有且仅有一个根结点,当n>1时,其余结点可以分为m(m>0)个互不相交的有限集每一个集合又是一棵树,称为根的子树。
结点的度:结点拥有的子树个数
(比如结点A的度为2)
叶结点(终端结点):度为0的结点
(比如结点G、H、I)
分支结点(非终端结点):度不为0的结点
内部结点:除了根结点之外的分支结点
树的度:树内某个拥有最大度的结点的度
(比如上图中树的度为3)
结点间的关系:
结点的孩子:结点的子树的根
(比如A的孩子为B和C)
结点的双亲:有孩子的结点称为该孩子的双亲
(比如B和C的双亲为A)
结点的兄弟:同一个双亲的孩子之间互称兄弟
(比如B和C互为兄弟)
结点的祖先:从根到该结点所经分支上的所所有结点
(比如H的祖先有D、B、A)
结点的子孙:以某结点为根的子树中任一结点都为该根结点的子孙。
(比如B的子孙有D、G、H、I)
结点的层次:从根开始定义起,根为第一层,根的孩子为第二层···
树的深度(高度):树中结点的最大层次
(该树的深度为4)
有序树与无序数:将树中结点看成从左至右是有次序的不能互换的,则为有序树,否则为无序数。
森林:m(m>=0)棵互不相交的树的集合
(比如上图的两个子树可以看作森林)
树的存储结构:
1.双亲表示法:
可以用数组来存储树,用数据域data来存储数据 ,用指针域parent来存储该结点的双亲在数组中的下标。因为根结点没有双亲,所以其指针域存储-1。上图可以用双亲表示法表示为:
双亲表示法可以通过parent指针快速找到某个结点的双亲,但是要找某个结点的孩子只能遍历整个数组。所以可以在双亲表示法上加一个该结点最左边的孩子指针域,叫做长子域。没有孩子的结点,其长子域存入-1。
如果很关注兄弟间的关系,可以加一个又兄弟域。如果该结点存在右兄弟,则把其右兄弟的下标存入rightsib,若没有右兄弟,则存入-1。
2.孩子表示法:
每个结点都创建一个单链表,把该结点的孩子存入链表中,且该结点为链表的头结点。然后把头结点存入一个一维数组中。
此时通过孩子表示法很容易找到某结点的孩子与兄弟,但是想要查找某结点的双亲就需遍历整棵树。可以把双亲表示法和孩子表示法结合起来,称为双亲孩子表示法,只需在每个头结点加一个指针域parent。
3.孩子兄弟表示法:
因为任何一个结点的第一个孩子如果存在就是唯一的,和其右兄弟如果存在也是唯一的。所以可以创建一个结构来存储树:一个数据域data,一个指向其第一个孩子的指针域firstchild,一个指向其右兄弟的指针域rightsib。