标签:
(1) 树的定义
树(Tree)是n(n>=0)个结点的有限集。n=0时称为空树。在任意一棵非空树中:
需要注意的是:
(2) 树的抽象数据类型
ADT 树(Tree)
Data
树是由一个根结点和若干棵子树组成。树中结点具有相同数据类型及层次关系。
Operation
initTree(&T):构造空树T。
destoryTree(&T):销毁树T。
createTree(&T, definition):按definition中给出树的定义来构造树。
clearTree(&T):若树T存在,则将树T清为空树。
treeEmpty(T):若T为空树,返回true,否则返回false。
treeDeep(T):返回T的深度。
root(T):返回T的根结点。
value(T, cur_e):cur_e是树T中的一个结点,返回此结点的值。
assign(T, cur_e, value):给树T的结点cur_e赋值为value。
parent(T, cur_e):若cur_e是树T的非根结点,则返回它的双亲,否则返回空。
leftChild(T, cur_e):若cur_e是树T的非叶子结点,则返回它的最左孩子,否则返回空。
rightSibling(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的度,操作结果为删除T中p所指结点的第i棵子树。
endADT
(3) 树的存储结构
双亲表示法
孩子表示法
孩子兄弟表示法
(1) 二叉树的定义
二叉树(Binary Tree)是n(n >= 0)个结点的有限集合,该集合或者为空集(称为空二叉树),或者由一个根结点和两棵互不相交的、分别称为根结点的左子树和右子树的二叉树组成。
特点:
二叉树的五种基本形态:
(2) 一些特殊的二叉树
斜树:
顾名思义,斜树一定要是斜的,但是往哪斜还是有讲究的。所有的结点都只有左子树的二叉树叫左斜树。所有结点都是只有右子树的二叉树叫右斜树。这两者统称为斜树。
满二叉树:
在一棵二叉树中,如果所有分支结点都存在左子树和右子树,并且所有的叶子都在同一层上,这样的二叉树称为满二叉树。
单是每个结点都存在左右子树,不能算是满二叉树,还必须要所有的叶子都在同一层上,这就做到了整棵树的平衡。因此,满二叉树的特点有:
完全二叉树:
对一棵具有n个结点的二叉树按层序编号,如果编号为i(1 <= i <= n)的结点与同样深度的满二叉树中编号为i的结点在二叉树中位置完全相同,则这棵二叉树称为完全二叉树。
完全二叉树的特点:
(3) 二叉树的性质
性质1:在二叉树的第i层至多有2i-1个结点(i >= 1)。
满二叉树每一层结点数最多,可以用归纳法得到结论。
性质2:深度为k的二叉树至多有2k-1个结点(k >= 1)。
由性质1可知:第1层最多1个结点,第2层最多2个结点,第3层最多3个结点,……,第k层至多2k-1个结点;
则一共最多(1 + 2 + 4 + …… + 2k-1) = 2k-1 个结点。
性质3:对任何一棵二叉树T,如果其终端结点数为n0,度为2的结点数为n2,则n0=n2+1。
终端结点数其实就是叶子结点数,而一棵二叉树,除了叶子结点外,剩下的就是度为1或度为2的结点数了,我们设n1为度为1的结点数。则树T结点总数为n=n0+n1+n2。
则二叉树中总的入度数为n-1,因为除根结点外,每个结点入度均为1。
二叉树中总的出度为n1+2n2,度为0的结点没有出度。
显然二叉树中有 入度=出度,即n1+2n2=n-1=n0+n1+n2-1,则n0=n2+1。
性质4:具有n个结点的完全二叉树的深度为[log2n]+1([x]表示不大于x的最大整数)。
它的总结点数一定少于等于同样深度的满二叉树的结点数2k-1,但一定多于2k-1-1。
即2k-1-1 < n <= 2k-1。
也即2k-1 <= n < 2k
两边取对数,可得到k-1 <= log2n < k
而k作为深度数也是整数,因此,k=[log2n]+1。
性质5:如果对一棵有n个结点的完全二叉树的结点按层序编号(从第1层到第[log2n]+1层,每层从左到右),对任一结点i(1<=i<=n)有:
1. 如果i=1,则结点i是二叉树的根,无双新;如果i>1,则其双新结点为[i/2];
2. 如果2i>n,则结点i无左孩子(结点i为叶子结点);否则其左孩子结点是2i;
3. 如果2i+1>n,是结点i无右孩子;否则其右孩子为2i+1。
(4) 二叉树的存储结构
二叉树的顺序存储结构
二叉树的顺序存储结构就是用一维数组存储二叉树中的结点,并且结点的存储位置,也就是数组的下标要能体现结点之间的关系,比如双亲与孩子的关系,左右兄弟的关系等。对于完全二叉树而言,层序编号即可反应逻辑关系。
对于一般的二叉树,尽管层序编号不能反映逻辑关系,但可以将其按完全二叉树编号,只不过,把不存在的结点设置为空而已。
考虑一种极端的情况,一棵深度为k的右斜树,它只有k个结点,却需要分配2k-1个存储单元空间,这显然是对存储空间的浪费,所以,顺序存储结构一般只用于完全二叉树。
二叉链表
二叉树的每个结点最多有两个孩子,所以为它设计一个数据域和两个指针域是比较自然的想法,我们称这样的链表叫做二叉链表。
以下是我们的二叉链表的结点结构定义代码:
typedef struct BiTNode { TElemType data; struct BiTNode *lchild, *rchild; } BiTNode, *BiTree;
如果需要,还可以再增加一个指向其双亲的指针域,那样就称为三叉链表。
标签:
原文地址:http://www.cnblogs.com/xiaoxxmu/p/5599483.html