C语言 题目 1698: 数据结构-线索二叉树

《大话数据结构》上的,大家可以参考一下 

 

 

题目描述

在遍历二叉树的过程中,是按照一定的规则将二叉树中的结点排列成一个线性序列,从而得到二叉树中结点的先序序列或中序序列或后序序列。但是,当以二叉链表作为存储结构时,只能找到结点的左右孩子信息,而不能直接得到结点在任意一个序列中的前驱和后继的信息,而这种信息只有在遍历的动态过程中才能够得到。
为了保存这种信息,就需要使用线索链表。其中指向结点的前驱和后继的指针,叫做线索。添加上线索的二叉树称之为线索二叉树。其结点定义如下:

下面给出按照中序遍历将二叉树中序线索化的算法:

在已经线索化的二叉线索树中,进行中序遍历的算法如下所示:

本题中,将会给出一个按照先序遍历得出的字符串,空格代表空的子节点,大写字母代表节点内容。请通过这个字符串建立二叉树,并按照题目描述中算法,中序遍历二叉树并中序线索化二叉树,之后中序遍历输出二叉线索树。

输入格式

输入只有一行,包含一个字符串S,用来建立二叉树。保证S为合法的二叉树先序遍历字符串,节点内容只有大写字母,且S的长度不超过100。

输出格式

共一行,包含一串字符,表示按中序遍历二叉线索树得出的节点内容,每个字母后输出一个空格。请注意行尾输出换行。

样例输入

<span style="color:#333333"><span style="color:#333333">ABC  DE G  F   </span></span>

样例输出

<span style="color:#333333"><span style="color:#333333">C B E G D F A </span></span>
#include<stdio.h>
#include<stdlib.h>
typedef enum{link,thread} pointerflag;
typedef struct BiTree{
	char c;
	struct BiTree *lchild,*rchild;
	pointerflag lflag;
	pointerflag rflag;
}*bitree,BITNODE;
bitree pre=NULL;//pre是全局变量,始终指向前驱结点 
void creattree(bitree *);//建立二叉树 
void thread_(bitree*,bitree);//线索化之前的准备 
void threading(bitree);//线索化 
void ThreadTraverse(bitree);//中序遍历 
int main(){
		bitree head=NULL;//指向头结点 
		bitree t=NULL;//指向根节点 
		creattree(&t);//创建根节点 
		thread_(&head,t);//线索化 
		ThreadTraverse(head);//中序遍历 
}
void creattree(bitree* t){
	char c;
	c=getchar();
	if(c==' '){
	(*t)=NULL;
	}
	else{
	(*t)=(bitree)malloc(sizeof(BITNODE));
	(*t)->c=c;
	creattree(&(*t)->lchild);
	creattree(&(*t)->rchild);
	}
}
void thread_(bitree* head,bitree t){
	(*head)=(bitree)malloc(sizeof(BITNODE));
	(*head)->lflag=link;
	(*head)->rflag=thread;
	(*head)->rchild=(*head);//右指针回指 
	if(!t)
	(*head)->lchild=*head;//左指针回指 
	else{
	(*head)->lchild=t;//有根结点 
	pre=(*head);
	threading(t);
	pre->rchild=*head;
	pre->rflag=thread;//最后一个结点线索化 
	(*head)->rchild=pre;
	}
}
void threading(bitree t){//线索化 
	if(t){
		threading(t->lchild);
		if(!(t->lchild)){
			t->lflag=thread;
			t->lchild=pre;
		}
		else
		t->lflag=link;
		if(!(pre->rchild)){
			pre->rflag=thread;
			pre->rchild=t;
		}
		else
		t->rflag=link;
		pre=t;
		threading(t->rchild);
	}	
}
void ThreadTraverse(bitree head){
	bitree p=head->lchild;//根结点开始 
	while(p!=head){
		while(p->lflag==link){//因为是中序遍历,所以先找最左的结点 
			p=p->lchild;
		}
		printf("%c ",p->c);
		while(p->rflag==thread&&p->rchild!=head){
			p=p->rchild;
			printf("%c ",p->c);
		}
		p=p->rchild;//意味着有右孩子,那么,p将成为新的根结点 
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值