赞
踩
树(Tree)是n(n≥0)个结点的有限集,它或为空树(n=0);或为非空树,对于非空树T:
1.结点: 树中的一个独立单元。包含一个数据元素及若干指向其子树的分支,如中的A、B、C、D等。
2. 结点的度: 结点拥有的子树数称为结点的度。例如,A的度为3,C的度为1,F的度为0。(注:度是n,就产生n条边)
3. 树的度: 树的度是树内各结点度的最大值。上图树的度为3。
4. 叶子: 度为0的结点称为叶子或终端结点。结点K、L、F、G、M、I、J都是树的叶子。
5. 非终端结点: 度不为0的结点称为非终端结点或分支结点。除根结点之外,非终端结点也称为内部结点。
6. 双亲和孩子: 结点的子树的根称为该结点的孩子,相应地,该结点称为孩子的双亲。例如,B的双亲为A,B的孩子有E和F。
7. 兄弟: 同一个双亲的孩子之间互称兄弟。例如,H、Ⅰ和J互为兄弟。
8. 祖先: 从根到该结点所经分支上的所有结点。例如,M的祖先为A、D和H。
9. 子孙: 以某结点为根的子树中的任一结点都称为该结点的子孙。如B的子孙为E、K、L和F。
10. 层次: 结点的层次从根开始定义起,根为第一层,根的孩子为第二层。树中任一结点的层次等于其双亲结点的层次加1。
11. 堂兄弟: 双亲在同一层的结点互为堂兄弟。例如,结点G与E、F、H、I、J互为堂兄弟。
12. 树的深度: 树中结点的最大层次称为树的深度或高度。图所示的树的深度为4。
13. 有序树和无序树: 如果将树中结点的各子树看成从左至右是有次序的(即不能互换),则称该树为有序树,否则称为无序树。在有序树中最左边的子树的根称为第一个孩子,最右边的称为最后一个孩子。
14. 森林: 是m ( m≥0)棵互不相交的树的集合。对树中每个结点而言,其子树的集合即为森林。由此,也可以用森林和树相互递归的定义来描述树。
为何要研究二叉树:
二叉树: 二叉树是n(n≥O)个结点的有限集,它或者是空集(n= 0),或者由一个根结点及两棵互不
相交的分别称作这个根的左子树和右子树的二叉树组成。
二叉树特点:
注:
(也就是二叉树每个结点位置或者说次序都是固定的,可以是空,但是不可以说它没有位置,而树的结点位置是相对于别的结点来说的,没有别的结点时,它就无所谓左右了),
满二叉树: —棵深度为k且有力2^k-1个结点的二叉树称为满二叉树。
特点:
完全二叉树: 深度为k 的具有n个结点的二叉树,当且仅当其每一个结点都与深度为k的满二叉树中编号为1~n的结点一一对应时,称之为完全二叉树。
下面是不是呢
特点:
具有n个结点的完全二叉树的深度为Llog2n」+ 1 。
注: Lx」:称作x的底,表示不大于x的最大整数
如果对一棵有n个结点的完全二叉树(深度为Llog2n」+1)的结点按层序编号(从第1层到第Llog2n」+1层,每层从左到右),则对任一结点i (1≤i≤n),有:
提要:
方式 | 顺序 | 链式 |
---|---|---|
1 | 一维数组 | 二叉链表 |
2 | x | 三叉链表 |
完全二叉树
非完全二叉树
节点构成:
结论:
节点构成:
DLR——先(根)序遍历,
LDR——中(根)序遍历,
LRD——后 (根)序遍历。
先序 | 中序 | 后序 |
---|---|---|
(1)访问根结点;(2)先序遍历左子树;(3)先序遍历右子树。 | (1)中序遍历左子树;(2)访问根结点;(3)中序遍历右子树。 | (1)后序遍历左子树;(2)后序遍历右子树;(3)访问根结点。 |
例1:三种遍历
答案:先ABELDHMIJ
中ELBAMHIDJ
后LEBMIHJDA
例2:中缀转后缀表达式
先序: - + ax b- c d / e f
中序: a + bx c - d - e / f
后序: a bc d -×+e f / -
前缀表达式,中缀表达式,后缀表达式一一对应先序,中序,后序。
由二叉树的先序序列和中序序列,或由二叉树的后序序列和中序序列可以确定唯一一棵二叉树
深度优先遍历(DFS):DLR, LDR, LRD
广度优先遍历(BFS)
Status PreOrderTraverse(BiTree T){
if(T==NULL) return OK;//空二叉树
else{
visit(T);//访问根结点 // // cout<<T->data;
PreOrderTraverse(T-> lchild);//递归遍历左子树
PreOrderTraverse(T-> rchild);//递归遍历右子树
}
}
Status InOrderTraverse(BiTree T){
if(T==NULL) return OK;//空二叉树
else{
InOrderTraverse(T->lchild);//递归遍历左子树
visit(T);//访问根结点; // cout<<T->data;
InOrderTraverse(T->rchild);//递归遍历右子树
}
}
Status PostOrderTraverse(BiTree T){//后序
if(T==NULL) return OK;
else{
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
cout<<T->data;
}
void InOrderTraverse (BiTree T){//中序遍历二叉树T的非递归算法 Initstack (S) ; p=T; q=new BiTNode; while(p|| !StackEmpty(S)) { if(p) //p非空 { Push(S,p); //根指针进栈 p=p-> lchild;//根指针进栈,遍历左子树 } else{ //p为空 Pop(S,q); //退栈 cout<<q- >data; //访问根结点 p=q-> rchild; //遍历右子树 } } }
层序遍历: 对于一颗二叉树,从根结点开始,按从上到下、从左到右的顺序;访问每一个结点。(注:用队列存储元素)
步骤:
void CreateBiTree (BiTree &T )
{//按先序次序输人二叉树中结点的值(一个字符),创建二叉链表表示的二叉树T
cin>>ch;
if(ch=='#') T=NULL;//递归结束,建空树
else//递归创建二叉树
{
T=new BiTNode; //生成根结点
T-> data=ch; //根结点数据域置为ch
CreateBiTree (T-> lchild) ;//递归创建左子树
CreateBiTree (T-> rchild); //递归创建右子树街小
}
}
先序遍历的思想
void Copy (BiTree T, BiTree . &NewT) {//复制一棵和T完全相同的二叉树 if (T==NULL)//如果是空树,递归结束 { NewT=NULL; return 0; } else { NewT=new BiTNode; NewT-> data=T-> data;//复制根结点 Copy (T-> lchild, NewT-> lchild) ;//递归复制左子树 Copy (T-> rchild, NewT-> rchild) ;//递归复制右子树 } }
后序遍历的思想
int Depth(BiTree T)
{//计算二叉树T的深度
if (T==NULL) return 0;//如果是空树,深度为0,递归结束
else
{
m=Depth (T->lchi1d) ;//递归计算左子树的深度记为m butol叫_
n=Depth (T->rchild) ;//递归计算右子树的深度记为n
if (m>n) return (m+1) ;//二叉树的深度为m与n的较大者加1
else return (n+1);
}
}
int NodeCount (BiTree T)
{//统计二叉树T中结点的个数
if (T==NULL) return 0;//如果是空树,则结点个数为0,递归结束
else return NodeCount (T->lchild) +NodeCount (T->rchild) +1;
//否则结点个数为左子树的结点个数+右子树的结点个数+1
}
p128
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。