大家好,好久没有发表文章了。最近忙项目,没有时间学习数据结构与算法。因为快放假了,公司没什么活。本人又不准备回老家,所以腾出时间来学习数据结构。今天,我们要学习的数据结构,可以说是最最重要,应用最广的数据结构-----树。好了,闲话不多说,我们开始吧。
树的概念:
图6-2-1就是一棵树,由图我们可以得出树的定义:树(Tree)是n(n≥0)个结点的有限集。n=0时,树为空树。(1)任一一棵非空的树,有且仅有一个称为根(Root)的结点。(2)n>1时,其余结点可以分为m(m>0)个互不相交的有限集T1、T2、…、Tm,其中每一个集合本身又是一棵树,并且称为根的子树(SubTree)。
如上图,结点A就是整棵树的根结点。
如上图,子树T1、子树T2、根结点A,构成了图6-2-1。
对于树的定义,一定要清楚亮点:
(1)、当n>1时,树有且只有一个根结点。
(2)、当m>0时,可以有无数个子树,但是它们不能够相交。(如下图:)
图6-2-3不是一根树,因为它们子树之间相交了。
结点的分类:
树的结点,包含数据元素和若干指向其子树的分支。结点中包含指向其子树分支的个数,就是结点的度。度数为零的结点,称为叶子结点。
度数不为零的结点,称为分支结点。分支结点中度数的最大值,称为树的度。
结点间的关系:
结点的子树的根结点称为该结点的孩子结点。该结点称为子树的根结点的双亲结点。具有相同双亲结点的结点,称为兄弟结点。从根到结点的所有分支上的结点,称为祖先结点。以某一结点为根的子树中的所有结点,都成为该结点的子孙结点。大家可以看一下下图:
树的一些其他概念:
树,还有一些别的概念。层:树的根节点在第一层上,它的孩子在它的下面层中。如果某结点在树的第i层,则它的子树的根节点就在i+1层,双亲结点在同一层的结点,成为堂兄弟。深度(Depth):树的最大层次,称为树的深度。森林(Forest):不相交的子树的集合成为森林。大家看下图:
最后,我们拿线性结构,与树结构做个比较。
线性结构:第一个数据元素:无前驱 最后一个数据元素:无后继 中间数据元素:一个前驱一个后继。
树结构:根结点无双亲,具有唯一性。中间结点有一个双亲多个孩子。叶子结点无双亲可以有多个。
树的抽象数据类型:
抽象数据类型,这个是非常重要的概念。它类似于,我们C#中的抽象类。顾名思义,它将同一种数据类型共用的属性、方法抽象出来。使我们可以大致的了解这个数据类型所具有的属性、方法等等。那我们想一下,树都具有哪些属性、方法呢?
ADT 树(tree)
Data
树是由一个根节点与多棵子树构成的。树中的所有结点具有相同的数据类型与层次关系。
Operation
InitTree(*T):构造空树T。
DestroyTree(*T):销毁树T。
CreateTree(definition,*T):按definition中给出的定义构建树T。
ClearTree(*T):若树T存在,则将树T清空为空树。
TreeEmpty(*T):若树T为空,则返回True,否则返回False。
TreeDepth(*T)返回树T的深度。
Root(*T)返回T的根结点。
Value(T,cur_e):cur_e是树中的结点,返回此结点的值。
Assign(T,cur_e,value):给T中结点cur_e赋值value。
Parent(T,cur_e)若cur_e不为根结点,返回它的双亲结点,否则返回空。
RightSibling(T,cur_e)若cur_e有右兄弟,则返回它的右兄弟结点,否则返回空。
LeftChild(T,cur_e)若cur_e不为叶子结点,返回它的左孩子结点,否则返回空。
InsertChild(*T,*p,i,c):p指向T中的某个结点,i为p指向结点的度+1,c为不与T相交的树。此操作将c插入树T,作为结点p的第i个孩子。
DeleteChild(*T,*p,i)p指向树T中的某个结点,i为p指向结点的度。此操作,输出p结点第i个孩子结点。
endADT
以上就是树抽象数据类型,上面的操作只是一些基本的,还有一些复杂操作,可以结合简单操作。
好了,我们这章只讲解树的一些基本概念,抽象数据类型。其他的一些知识,我们下篇文章再讲。
总结:
我们来总结一下,这篇文章讲到的知识。首先,我们学习了树的定义。树是由一个根结点与多棵互不相交的子树构成。我们学习了,结点的分类。根结点、双亲结点、兄弟结点、叶子结点。还学习了,树的其他一些概念,森林,度等。最后,我们总结了树的抽象数据类型,使我们了解了树的一些基本操作。