树与二叉树转换
•
return (lh>rh? lh: rh)+1; //最大深度+1
•}
• else return 0;
•}
•}
第9页/共20页
三、构造二叉树
• 给定二叉树的一种遍历结果是无法确定二叉树的; • 恢复二叉树指:根据给定的两种遍历结果,反推出该
二叉树。 • 给定2 种遍历结果(中序、先序;或中序、后序)可唯
• 要求输入时表示出叶子结点。 • 如图所示:
• 输入序列为: • ABD#GL###E##CFH##K### • 其中的 # 表示空
A
B
C
D
EF
G
H
K
L
第6页/共20页
算法6.4 按扩展先序序列建立二叉树的算法
• typedef char elemtype ;
/* 结点数据为char型 */
• bitree creatbit()
/* 遍历左子树(递归调用) */
preorder(root->rchild);
/* 遍历右子树(递归调用) */
}
}
第1页/共20页
中序遍历二叉树的递归算法
void Inorder(bitree root)
/* root为根结点,visit()为访问结点的函数 */
{ if ( root !=0)
第8页/共20页
• //统计二叉树深度的算法
• int deepth(tnode *root)
• { int lh,rh;
• if (root)
//二叉树非空
•{
•
lh=deepth(root->lchild); //统计左子树深度
•
rh= deepth(root->rchild); //统计右子树深度
/* root为根结点,visit()为访问结点的函数 */
{ if ( root !=0)
/* 二叉树非空 */
{ PostOrder(root->lchild); PostOrder(root->rchild); visit(root->data);
/* 遍历左子树(递归调用) */ /* 遍历右子树(递归调用) */ /* 访问根结点 */
• /* 按输入的前序序列建立二叉树,输入以回车表示结束 */
• /* 若创建成功,返回该二叉树的根,否则返回空指针 */
• { char ch;
• bitree T;
• scanf(“%c”,&ch);
• if (ch==’#’) return (0);
/* 返回空二叉树 */
• else
• { T=(bitree)malloc(sizeof(bnode));
void BTlayer( bitree root) {
linkqueue Q; bitree P=root; Init_queue(Q); if (root) In_queue(Q,root); while ( Q.front) {
P=dele_queue(Q); printf(“%c”,P->data); if (P->lchild) In_queue(Q,P->lchild); iP->rchild); }
遍历二叉树的递归算法
算法6.1 前序遍历二叉树的递归算法
void preorder(bitree root)
/* root为根结点,visit()为访问结点的函数 */
{ if ( root !=0)
/* 二叉树非空 */
{
visit(root->data);
/* 访问根结点 */
preorder(root->lchild);
1)初始化队列Q; 2)将根结点入队列; 3)当队列Q不空时,重复以下过程: { 对头元素出队列,并访问该结点;
若该结点左孩子非空,访问左孩子并将左孩子入队; 若结点右孩子非空,访问右孩子并将右孩子入队; } 实际上,结点的访问次序就是其进入队列的次序。
第4页/共20页
二叉树层次遍历的算法(应用辅助队列)
一确定一棵二叉树; 注意:必须包括中序遍历。
第10页/共20页
练习:
• 1.由前序和中序遍历的序列构造二叉树 • 2.由后序和中序遍历的序列构造二叉树
2020/6/11
第11页/共20页
6.4 树、森林与二叉树的转换
1.树与二叉树的对应关系
树与二叉树均可用二叉链表作为存储结构,因此给定一棵树, 用二叉链表存储,可唯一对应一棵二叉树,反之亦然。
/* 生成“根”结点 */
•
T->data=ch;
•
T->lchild=creatbit();
/* 创建左子树 */
•
T->rchild=creatbit();
/* 创建右子树 */
•
return (T);
/* 返回根 */
•}
•}
第7页/共20页
遍历算法的应用
在遍历算法的基础上完成以下算法: 1.统计二叉树中的叶子结点个数 2.求二叉树的深度 3.统计二叉树中的结点总数
}
}
第3页/共20页
4. 二叉树的层次遍历
二叉树的层次遍历:即按照“从上到下,从左至右”的次序访问所有结点 一次且仅一次。对一棵非空的二叉树,先访问根结点,再依次访问左孩子、 右孩子,并记录该层结点的访问次序;依次访问各结点的左孩子和右孩子, 直到访问到最右端的叶子结点。
层次遍历存在容易理解的非递归算法。这里有一个“依序访问下层结点” 的问题,为了记录上一层结点的访问次序,需要使用队列。算法描述如下:
2.树转换成二叉树
将一棵树转化为等价的二叉树方法如下:
(1) 在树中各兄弟(堂兄弟除外)之间加一根连线。
(2) 对于任一结点,只保留它与最左孩子的连线,删去它与其余 孩子之间的连线。
/* 二叉树非空 */
{ Inorder(root->lchild); visit(root->data); Inorder(root->rchild);
/* 遍历左子树(递归调用) */ /* 访问根结点 */ /* 遍历右子树(递归调用) */
}
}
第2页/共20页
后序遍历二叉树的递归算法
void PostOrder(bitree root)
//辅助队列 /* P指向根结点 */ /* 初始化队列 */ /* 根结点入队 */ /* 队列Q不空时继续 */
/* 出队,队头元素=>P */ /* 访问结点数据 */ /* 左孩子入队 */ /* 右孩子入队 */
}
第5页/共20页
二、二叉树的建立算法(实验需掌握)
• 按扩展的先序序列建立二叉树的算法