//定义一个链式二叉树
typedef int datatype;
struct Treenode{
datatype data;
struct Treenode *lchild,*rchild;
};
struct Treenode *root;
//设定三个指针分别指向左孩子,右孩子和根
//建立链式存储二叉树
//依次输入结点信息,如果不是虚结点就建立一个新结点
//如果新结点是第一个结点,令其为根结点。否则作为孩子连接到他的双亲上。直至输入‘# ’
//实际上是一个队列的操作。
Treenode CREATETREE(struct Treenode *s){
int rear;
while((ch=getchar())!='#'){
s=NULL;
if(ch!='@'){ //@表示虚结点,如果不是虚结点就建立新结点
s=(struct Treenode*)malloc(sizeof (struct Treenode));
s->data=ch;
s->lchild=NULL;
s->rchild=NULL; //左右孩子置空
}
rear++; //队尾指针+1
Q[rear]=s; //将新结点地址入队
if(rear==1) root=s; //输入的第一个结点作为根节点
else{
if(s&&Q[front]) //孩子和双亲都不是虚结点
if(rear%2==0)Q[front]->lchild=s; //rear是偶数,新结点是左孩子
else Q[front]->rchild=s; //rear是奇数,新结点是右孩子
if(rear%2==1) front++; //两个孩子处理完毕,出队列
}
}
return root; //返回根指针
}
二叉树的遍历
指按某种搜索路线巡防二叉树中的每一个结点,分为深度优先遍历和广度优先遍历。
递归算法:
//先序遍历算法
void preorder(struct Treenode *p){
if(p!=NULL){
printf("%c",p->data);
preorder(p->lchild); //先序遍历左孩子 递归算法
preorder(p->rchild);
}
}
//中序遍历算法
void inorder(struct Treenode *p){
if(p!=NULL){
inorder(p->lchild);
printf("%c",p->data);
inorder(p->rchild);
}
}
//后序遍历算法
void postorder(struct Treenode *p){
if(p!=NULL){
postorder(p->lchild);
postorder(p->rchild);
printf("%c",p->data);
}
}
非递归算法:
中序遍历的非递归算法
当p的结点非空时,将该结点的存储地址入栈,将p指向结点的左孩子
p结点为空时,从栈顶退出栈顶元素送p,访问该节点,p指向结点的右孩子结点
直到p为空且栈顶指针top==-1
广度优先遍历:
又称为按层次遍历,对每一层从左往右遍历。
使用一个队列。先把根节点的存储地址入队,然后依次从队列中出队结点的存储地址,没出队一个结点的存储地址则对该结点进行访问,依次将结点的左右孩子入队,直到队空。
//广度优先遍历
void layer(struct Treenode *p){
struct Treenode *Q[maxsize];
struct Treenode *s;
if(p!=NULL){
rear=0;
front=-1; //队头队尾置初值
Q[rear]=p; //根节点入队
while(front<rear){ //判断队列非空
front++;
s=Q[front]; //从队列中出队队头结点
printf("%c",p->data); //访问出队结点
if(s->lchild!=NULL){ //左孩子结点入队
rear++;
Q[rear]=s->lchild;
}
if(s->rchild!=NULL){ //右孩子结点入队
rear++;
Q[rear]=s->rchild;
}
}
}
}
从遍历序列恢复二叉树
先序和中序,中序和后序可以唯一确定一颗二叉树。
已知一颗二叉树先序序列为ABDGCEFH,中序序列为DGBAECHF,确定二叉树的算法:
从先序可知A是二叉树的根节点。再根据A在中序中的位置,可知结点DGB在A的左子树,ECHF在右子树。
先序确定BC是A的左子树和右子树的根,根据BC在中序中的位置,得出DG在B的左子树,B的右子树为空。以此类推。最后确定,H是F左子树的根。
递归算法的思想:
先将先序和中序分别存在perod[n] 和inod[n]中。
取先序序列的第一个元素为根节点,利用中序确定根节点的左右子树结点。进行构造。
具体代码实现:
datatype preod[maxsize],inod[maxsize];
struct Treenode *BPI(datatype preod[],datatype inod[],int ps,int pe,int is,int ie){
int m;
struct Treenode *p;
p=(struct Treenode *)malloc(sizeof(struct Treenode)); //构造根结点
p->data=preod[ps];
m=is;
while(inod[m]!=preod[ps]) m++; //查找根结点在中序序列中的位置
if(m==is) p->lchild=NULL; //对左子树进行构造
else p->lchild=BPI(preod,inod,ps+1,ps+m-is,is,m-1);
if(m==ie) p->rchild=NULL; //对右子树进行构造
else p->rchild=BPI(preod,inod,ps+m-is+1,pe,m+1,ie);
return p;
}