树是n个节点的有限集合T,若n=0则称为空树,否则:
有且只有一个特殊的称为树的根结点;
若n>1,其余的结点被分为m个(m>0)互不相交的子集T1,T2....Tm,其中每个子集本身又是一颗树,称其为根的子树。
各名词解释
1.结点:树的结点包含一个数据元素及若干指向其子树的分支。
2.结点的度:结点拥有的子树个数成为结点的度。
3.树的度:树的度是树内各结点的度的最大值。
4.叶子节点(终端结点):度为0的结点称为叶子或终端结点。(后面为空的结点)
5.非终端结点(分支结点):度不为0的结点。除根结点之外,分支结点也成为内部结点。
6.孩子结点:结点的子树的根称为孩子结点。
7.双亲结点:生成子树的结点称为双亲结点。
8.结点的兄弟:同意双亲的孩子之间互称为兄弟。
9.树的深度:树中结点的最大层次称为树的深度或高度。
10.结点的层次:从根开始定义,根为第一层,根的孩子为第二层。
11.森林:m棵互不相交的树的集合。对于树中每个结点而言,其子树的集合称为森林。
12.有序树和无序树:如果将树中结点的各子树看成从左至右是有次序的(即不能互换),则称该树为有序树,否则称为无序树。有序树中最左边的子树称为第一个孩子,最右边的称为最后一个孩子。
13.树的路径长度:是指树根到每个结点的路径长的总和。根到每个结点的路径的最大值应该是树的高度-1。
树的相关性质:
1)树中的结点数等于所有结点的度数加1.
2)度为m的树中第i层上至多有m的i-1次方个结点。(i>=1)
3)高度为h的m叉树至多有(m的h次方 - 1)/(m-1)个结点。
4)具有n个结点的m叉树的最小高度为【logm(n(m-1)+1)】
树中结点总数为n,度为i的结点树为ni,n=分支数+1,分支数又等于树中各结点的度之和。
n=1+1*n1+2*n2+3*n3+...+n*ni 总分支数
n=n0+n1+n2+...+ni 总结点数
二叉树:
有且只有一个特殊的称为树的根结点;
若n>1,其余的结点被分为二个互不相交的子集T1,T2,分别称之为左、右子树,并且左右子树又都是二叉树。二叉树是有序树,若将其左右子树颠倒,就成为另一棵不同的二叉树。即使树中结点只有一棵子树,也要区分它是左子树还是右子树。
二叉树的性质:
1.非空二叉树的叶子节点数等于度为2的结点数+1,即n0=n2+1
2.在非空二叉树中,第 i 层上至多有 2的 (i - 1)次方 个结点。
3.深度为k的二叉树至多有 2的k次方-1 个结点。
4.对任何一棵二叉树,若其叶子结点数为n0,度为2的结点数为n2,则n0=n2+1(叶子节点=分支结点+根结点)
5.n个结点的完全二叉树深度为【log2(n+1)】或【log2 n】+1 (向下取整,2为底数)
6.若对一棵有n个结点的完全二叉树的结点按层序自左至右进行编号,则对于编号为i的结点:
若i=1:则结点i是二叉树的根,五双亲结点;否则,若i>1,则其双亲结点编号是 i/2.
若2i>n:则结点i为叶子结点,无左孩子;否则,其左孩子结点编号是2i。
若2i+1>n:则结点i无有孩子;否则,其有孩子结点编号是2i+1.
满二叉树:
一颗高度为h,并且包含有2的h次方 -1 个结点的二叉树称为满二叉树,即树中的每一层都含有最多的结点。满二叉树的叶子结点都集中再二叉树的最下一程,并且除叶子结点之外的每个结点度数均为2。
完全二叉树:
如果深度为k,由n个结点的二叉树,当且仅当其每一个结点都与深度为k的满二叉树中编号从1到n的结点一一对应,该二叉树称为完全二叉树。满二叉树是完全二叉树的特例。
若有度为1的结点,则只可能有一个,且该结点只有左孩子而无右孩子。
完全二叉树中,n1=1或0;
当有2k个结点时,n0=k,n2=k-1,n1=1
当有2k-1个结点时,n0=k,n2=k-1,n1=0
二叉排序树:
一棵二叉树或者是空二叉树,或者是具有如下性质的二叉树:左子树上所有结点的关键字均小于根结点的关键字;右子树上的所有结点的关键字均大于根结点的关键字。左右子树又是一棵二叉排序树。
二叉排序树的查找:
BSTNode *BST_Search(BiTree T,Elemtype key){
while(T!=NULL&&key!=T->data){
if(key<T->data) T=T->lchild;
else T=T->rchild;
}
return T;
}
二叉排序树的插入
int BST_Insert(BiTree &T,KeyType K){
if(T==NULL){
T=(BiTree)malloc(sizeof(BSTNode));
T->key=k;
T->lchild=T->rchild=NULL;
return 1;
}
else if(k==T->key)
return 0;
else if(k<T->key)
return BST_Insert(T->lchild,k);
else
return BST_Insert(T->rchild,k);
}
在二叉排序树中进行查找的效率与 二叉排序树的深度有关。
平衡二叉树:
树上任一结点的左子树和右子树的深度之差不超过1。
平衡因子:结点左子树与右子树的高度差。取值为-1,0,1。
若出现不平衡的删除或添加,则每次应对最小不平衡树进行调整。
1)LL平衡旋转:由于在结点A的左孩子L的左子树L上插入了新的结点,A的平衡因子由a加1,导致以A为根的子树失去平衡,需要一次向右的旋转操作,将A的左孩子B向右上旋转代替A成为根结点,将A结点向右下旋转成为B的右子树的根结点,而B的原右子树则作为A结点的左子树。
2)RR平衡旋转:由于在结点A的右孩子R的右子树R上插入了新的结点,A的平衡因子由a减1,导致以A为根结点的子树失去平衡,需要一次向左的旋转,将A的右孩子B向左上旋转代替A成为根结点,将A结点向左下旋转成为B的左子树的根结点,而B的原左子树则成为A结点的右子树。
3)LR平衡旋转:由于在A的左孩子L的右子树R上插入新的结点,A的平衡因子由a加1,导致以A为根结点的子树失去平衡,需要旋转俩次,先左旋转后右旋转,先将A结点的左孩子B的右子树的根结点C向左上旋转提升到B结点的位置,然后把该C结点向右上旋转提升到A结点的位置。
4)RL平衡旋转:由于在A的右孩子R的左子树L上插入了新的结点,A的平衡因子由a-1,导致以A为根结点的子树失去平衡,需要旋转俩次,先右旋转后左旋转,先将A结点的右孩子B的左子树的根结点C向右上旋转提升到B结点的位置,然后把该C结点向左上旋转提升到A结点的位置。
含有n个结点的平衡二叉树的最大深度为O(log2 n),因此平衡二叉树的平均查找长度为O(log2 n)
先序遍历:根左右
中序遍历:左根右
后序遍历:左右根
层次遍历:根结点开始遍历,按层次次序自上而下,从左至右访问结点。
按中序遍历二叉排序树得到的序列是一个有序序列。
唯一能确定二叉树必有中序遍历。(判断左右子树)。
并且二叉树再线索化后,仍不能有效解决的问题是:后续线索二叉树中求后序后继。
前序序列和中序序列的关系相当于以前序序列为入栈次序,以中序序列为出栈次序,因为前序序列和中序序列可以唯一地确定一棵二叉树,所以对于不同n个元素进栈,出栈序列的个数为 (1/n+1)C(n,2n)。
树到二叉树的转变:
采用“左孩子右兄弟”的方法,规则如下:每个结点左指针指向它的第一个孩子,右指针指向它在树中的相邻兄弟。由于根兄弟没有兄弟,所以对应的二叉树没有右孩子。
树转换成二叉树的画法:1.在兄弟之间加一条线;2.对每个结点,只保留它与第一个孩子的连线,而与其他孩子的连线全部抹掉;3.以树根为轴心,顺时针旋转45°。
森林转二叉树的画法:1.将森林中的每棵树转换成相应的二叉树;2.每棵树的根也可视为兄弟关系,在每棵树的根之间加一根线连线;3.以第一棵树的根为轴心顺时针旋转45°。
树的先根遍历=二叉树的先序遍历
树的后根遍历=二叉树的后序遍历
哈夫曼树:
从树的根结点到任意结点的路径长度(经过的边数)与该结点上权值的乘积,称为该结点的带权路径长度。树中所有叶结点的带权路径长度之和称为该树的带权路径长度,记为WPL
在n个带权叶节点的二叉树中,其中带权路径长度WPL最小的二叉树称为哈夫曼树,也称最优二叉树。