二叉树1


//定义一个链式二叉树 
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;
}
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值