大话数据结构(第六章 树)
树:是n个节点的有限集。n=0时称为空树。在任意一颗非空树中:
有且仅有一个根(Root)节点
当n>1时,其余节点可分为m(m>0)个互不相交的有限集T1,...,Tn,其中每一个集合本身又是一颗树,并称之为根的子树(SubTree)。
注意:定义中就写明了:根节点只有一个;子树不相交;
1、节点分类
节点拥有的子树数称为节点的度(Degree)。
度为0的节点称为叶节点(Leaf)或终端节点;
度不为0的节点称为非终端节点或分支节点;
除了根节点外,分支节点称为内部节点;
树的度是树内各节点的度的最大值;
2、节点间的关系
节点子树的根称为该节点的孩子(Child),相应的,该节点称为孩子的双亲;同一个双亲的孩子之间互称为兄弟;节点的祖先是从根节点到该节点所经历分支上的所有节点,反之,以某节点为根的子树中的任一节点都称为该节点的子孙;
节点的层次:从根开始定义,根为第一层,根的孩子为第二层,依次类推;
双亲在同一节点互为堂兄弟。
树节点的最大层次称为树的深度或者高度。
有序树:树中节点的各个子树从左至右是有次序的,不能互换的
无序树:非有序树;
森林是M课互不相交的树的集合;
3、树的抽象数据类型
...
4、树的存储结构
利用顺序存储结构和链式存储结构的特点,可以实现对树的存储结构表示,这里有三种表示法:双亲表示法、孩子表示法、孩子兄弟表示法;
双亲表示法:假设一组连续空间存储树的节点,每个节点附有指示双亲节点到链表中的位置。
双亲表示法中所有节点都存有双亲节点的位置,根节点的位置域设为-1;
增加一个长子域,存储节点可能存在的第一个左边的孩子,没有就-1
也可以增加一个右兄弟域,如果不存在,记为-1
如果节点的孩子很多,超过2个。我们又关注节点的双亲、又关注节点的孩子,还关注节点的兄弟,而且对事件遍历要求还比较高,那么我么你还可以把此结构扩展为双亲域,长子域,再有右兄弟域。存储结构的设计是一个非常灵活的过程。合理性取决于存储结构的运算是否合适、是否方便,时间复杂度好不好等。
孩子表示法:每个节点有多个指针域,指向其它子树的根节点,称为多重链表示法。
一般一个树的度是n,我们就把每个节点的指针域定为三个;(似乎有点浪费时间)
每个节点的指针域的个数等于该节点的度,我们专门取一个位置存储节点指针的个数。(似乎浪费了运算时间)
把每个节点的孩子节点排列起来,以单链表作为存储结构,则n个节点有n个孩子链表,如果是叶子节点,则此链表为空,然后n个头指针组成一个线性表,采用顺序存储结构,存放在一个一维数组中。
为此有两种节点结构,一种是孩子链表的孩子节点,由数据与和指针域组成。指针域装着某个节点的下一个汉子节点;
另一个是表头数组的表头节点,有数据域和指针域,指针域装着第一个孩子的节点。
也可以在表头指针域中添加双亲指针域,用于查询该节点的双亲,这称作双亲孩子表示法。
孩子兄弟表示法,每个节点有两个指针域,放第一个孩子和右兄弟,这种表示法将一颗复杂的树变成了一颗二叉树了。
5、二叉树的定义
二叉树是n个节点的有限合集,该集合或者为空集(称为空二叉树),或者由一个根节点和两颗互不相交的、分别称为根节点的左子树和右子树的二叉树组成。
特点:度最大2. 左子树和右子树是有顺序的。 即使某节点只有一颗子树,也要区分是左子树还是右子树。
二叉树的五种形态:空二叉树,只有一个根节点,根节点只有左子树,根节点只有右子树,根节点既有左子树又有右子树。
一些特殊的二叉树:
斜树:所有节点只有左子树
满二叉树:所有分支节点都存在左子树和右子树,所有叶子都在同一层上;
完全二叉树:对一颗具有n个节点的二叉树按层序编号,如果编号i(1<=i<=n)的节点与同样深度的满二叉树的编号为i的节点在二叉树中的位置完全想听,则这颗二叉树称为完全二叉树。
6、二叉树的性质
1、在二叉树的第i层上之多有2的i-1次方个节点;
2、深度为k的二叉树至多有2的k次方-1个节点。
3、对任何二叉树T,如果终端节点数为n0,度为2的节点数为n2. 则n0 = n2 +1
4、具有n个节点的完全二叉树的深度为[log2n]+1
5、二叉树性质5.。。。暂时没写(这些性质还是使用的时候查阅把)
7、二叉树的存储结构
一颗完全二叉树按照层序一层一层的进行存储,存储在一维数组中,进行顺序存储;
如果二叉树每个节点最多有两个孩子,可以用一个数据域+两个指针域的方法,即二叉链表;
8、遍历二叉树
指从根节点出发,按照某种次序依次访问二叉树中所有节点,使得每个节点被访问一次仅被访问一次;
前序遍历:先根节点,前序遍历左子树再前序遍历右子树
中序遍历:中序遍历,根节点在左子树,最后右子树
后续遍历:根节点在右子树,最后左子树;
层序遍历:一层层的遍历,从根节点开始;
关于各种遍历法的调用方法的具体实现,大家可以自己看;
9、二叉树的建立
10、线索二叉树
如果所用的二叉树需经常遍历或查找节点时需要某种遍历序列中的前驱序列和后继,那么采用线索二叉链表的存储结构是非常不错的选择;
11、树、森林与二叉树的转换
。。。未看,省略、、、
12、赫夫曼树
...一种二叉树编码法。。。稍后写