目录
一、二叉树的定义
*几种特殊的二叉树
*二、二叉树的性质
三、二叉树的存储结构
*四、二叉树的遍历
*4.1先序遍历
* 4.2中序遍历
* 4.3后序遍历
非递归算法遍历
*4.4层序遍历
*五、遍历序列构造二叉树
六、线索二叉树
6.1逻辑结构:
* 6.2构造线索二叉树
一、二叉树的定义
二叉树是另一种树形结构,其特点是每个结点至多只有两课子树,并且二叉树的子树有左右之分,其次序不能任意颠倒
空二叉树,即n=0
*几种特殊的二叉树
1.1满二叉树:一般高度为h,含有 个结点的二叉树称满二叉树,每层都含最多结点4
1.2完全二叉树:高h,有n个结点的二叉树,当且仅当其每个结点都与高度为h的满二叉树中编号为1~n的结点一一对应,称完全二叉树
1)有度为1的结点,则只可能有一个,有左孩子无右孩子
2)若n为奇数,则每个分支都有左孩子和右孩子
若n为偶数,编号最大的结点(n/2)只有左孩子,没有右孩子,其余分支结点左右孩子都有
1.3二叉树排序树:左子树上所有结点的关键字均小于根结点的关键字;右大于左关键字,左子树和右子树又各是一颗二叉排序树
1.4平衡二叉树:树上任一结点的左子树和右子树的深度之差不超过 1
*二、二叉树的性质
1)
2)第k层上至多有个结点
3)高度为h的二叉树至多有个结点
4)完全二叉树顺序编号有以下关系
i的双亲结点为 ,i为偶数它是左孩子,奇数右孩子
时,结点i的左孩子编号为 2i ,否则无左孩子
时,结点i的右孩子编号为 2i+1 ,否则无右孩子
结点i的深度为:
5)具有n个结点的完全二叉树的高度为或
三、二叉树的存储结构
3.1顺序存储结构
3.2链式存储结构
typedef struct BiTNode{
int data; //数据域
struct BiTNode *lchild,*rchild; //左,右孩子指针
}BiTNode , *BiTree;
*四、二叉树的遍历
*4.1先序遍历
先访问根结点 ->左子树->右子树
void PreOrder(BiTree T){
if(T!=NULL){
viisit(T); //访问根结点
PreOrder(t->lchild); //递归访问左子树
PreOrder(t->rchild); //递归访问右子树
}
}
* 4.2中序遍历
左子树->访问根结点 ->右子树
void InOrder(BiTree T){
if(T!=NULL){
PreOrder(t->lchild); //递归访问左子树
viisit(T); //访问根结点
PreOrder(t->rchild); //递归访问右子树
}
}
* 4.3后序遍历
左子树->右子树 ->访问根结点
void PostOrder(BiTree T){
if(T!=NULL){
PostOrder(T->lchild); //递归访问左子树
PostOrder(T->rchlid); //递归访问右子树
visit(T); //访问根结点
}
}
非递归算法遍历
栈辅助
void InOrder(BiTree T){
InitStack(S);
BiTree p=T;
while( p || IsEmpty(S)){
if(p){
push(S,p);
p=p->lchild;
}else{
pop(S,p);
visit(p);
p=p->rchild;
}
}
}
*4.4层序遍历
队列辅助
void LevelOrder(Bitree T){
InitQueue(Q);
BiTree p;
EnQueue(Q,p);
while(!IsEmpty(Q)){
DeQueue(Q,P);
visit(p);
if(p->lchild!=NUll)
EnQueue(Q,p->lchild);
if(p->rchild!=NULL)
EnQueue(Q,p->rchild);
}
}
*五、遍历序列构造二叉树
例:先序序列(ABCDEFGHI) 中序序列(BCAEDGHFI)
六、线索二叉树
在n个节点的二叉树中,有n+1个空指针
空指针总数,又,所以空指针总数为
6.1逻辑结构:
tpyedef struct ThreadNode{
int data;
struct ThreadNode *lchild,*rchild;
int ltag,rtag;
}ThreadNode,*ThreadTree;
如lchild无左子树,指向结点前驱,如rchild无右子树,指向结点后继。
ltag表示指向是左孩子还是前驱,rtag表示指向是右孩子还是后继。
* 6.2构造线索二叉树
先序线索二叉树,中序线索二叉树,后续线索二叉树
通过中序遍历构造中序线索二叉树
void InThread(ThreadTree &p,ThreadTree &pre){
if(p!=NULL){
InThread(p->lchlid,pre);
if(p->lchild==NULL){
p->lchild=pre;
p->ltag=1;
}
if(pre!=NULL&&pre->rchild==NUll){
pre->rchild=p;
pre->rtag=1;
}
pre=p;
InThread(p->rchlid,pre);
}
}
void CreatrInThread(ThreadTree T){
ThreadTree pre=NULL;
if(T!=NULL){
InThread(T,pre);
pre->rchild=NUll;
pre->tag=1;
}
}