C语言实现线索二叉树

学数据结构的时候没有学线索二叉树,现在考研需要,补上了。
线索二叉树中给每个节点加上标记,使叶节点的空的数据域填上前驱或者后继,使得线索二叉树能快速的找到前驱后继
C语言实现线索二叉树_第1张图片

中序线索二叉树

C语言实现线索二叉树_第2张图片
线索化时如节点左子树为空,则添加前驱;设置全局变量pre,保存上一个访问的节点,访问下一个节点时,如果pre右子树为空,则pre的后继连上此节点。

#include
#include
#define N 100
typedef int ElemType;
typedef struct ThreadNode{
	ElemType data;
	struct ThreadNode *lchild,*rchild;
	int ltag,rtag;		//左右线索 
}ThreadNode,*ThreadTree;
ThreadNode *pre=NULL;
void visit(ThreadNode *q){			
	if(q->lchild==NULL){
		q->lchild=pre;
		q->ltag=1;
	}
	if(pre&&pre->rchild==NULL){
		pre->rchild=q;
		pre->rtag=1;
	}
	pre=q;
}
void InThread(ThreadTree T){		//边遍历边线索化 
	if(T){
		InThread(T->lchild);
		visit(T);				//后序调一下位置即可 
		InThread(T->rchild);
	}
}
void CreatInThread(ThreadTree T){	//线索化二叉树 
	pre=NULL;
	if(T){
		InThread(T);
		if(pre->rchild==NULL){		//如果最后一点为空,给他加标记 
			pre->rtag=1;			
		}
	}
}

ThreadNode *Firstnode(ThreadNode *p){			//p的第一个被中序遍历的节点 
	while(p->ltag==0) p=p->lchild;
	return p;
}
ThreadNode *Nextnode(ThreadNode *p){			//中序线索二叉树中p的后继 
	if(p->rtag==0) return Firstnode(p->rchild);
	else return p->rchild;
}
void Inoder(ThreadNode *T){						//非递归中序遍历二叉树 
	ThreadNode *p;
	for(p=Firstnode(T);p!=NULL;p=Nextnode(p)){
		printf("%d ",p->data);
	}
	printf("\n");
}

ThreadNode *Lastnode(ThreadNode *p){			//p的最后一个被中序遍历的节点 
	while(p->rtag==0) p=p->rchild;
	return p;
}
ThreadNode *Prenode(ThreadNode *p){				//中序线索二叉树中p的前继 
	if(p->ltag==0) return Lastnode(p->lchild);
	else return p->lchild;
}
void RevInoder(ThreadNode *T){					//非递归逆向中序遍历二叉树 
	ThreadNode *p;
	for(p=Lastnode(T);p!=NULL;p=Prenode(p)){
		printf("%d ",p->data);
	}
	printf("\n");
}

ThreadTree Creat(ThreadTree T,int x){
	if(!T){
		ThreadTree T=(ThreadTree)malloc(sizeof(ThreadNode));
		T->data=x;
		T->lchild=T->rchild=NULL;
		T->ltag=T->rtag=0;
	}
	else {
		if(x>T->data){
			T->rchild=Creat(T->rchild,x);
		}
		else{
			T->lchild=Creat(T->lchild,x);
		}
	}
}
int main()
{
	int i,j,k;
	int a[10]={2,5,6,9,3,4,7,8,1,0};
	ThreadTree T;
	for(i=0;i<9;i++){
		T=Creat(T,a[i]);		
	}
	CreatInThread(T);
	Inoder(T);
	RevInoder(T); 
	return 0;
}

先序线索二叉树

先序线索二叉树实现同中序基本一致,要注意的点是左边节点的数据可能是线索并不是真正的左子树,所以在遍历的时候加上一个判断条件。
C语言实现线索二叉树_第3张图片

#include
#include
#define N 100
typedef int ElemType;
typedef struct ThreadNode{
	ElemType data;
	struct ThreadNode *lchild,*rchild;
	int ltag,rtag;		//左右线索 
}ThreadNode,*ThreadTree;
ThreadNode *pre=NULL;
void visit(ThreadNode *q){			
	if(q->lchild==NULL){
		q->lchild=pre;
		q->ltag=1;
	}
	if(pre&&pre->rchild==NULL){
		pre->rchild=q;
		pre->rtag=1;
	}
	pre=q;
}
void PreThread(ThreadTree T){		//边遍历边线索化 
	if(T){
		visit(T);
		if(T->ltag==0){				//防止左边为线索无限循环的问题 
			PreThread(T->lchild);		
		}
		PreThread(T->rchild);
	}
}
void CreatPreThread(ThreadTree T){	//线索化二叉树 
	pre=NULL;
	if(T){
		PreThread(T);
		if(pre->rchild==NULL){		//如果最后一点为空,给他加标记 
			pre->rtag=1;			
		}
	}
}
ThreadTree Creat(ThreadTree T,int x){
	if(!T){
		ThreadTree T=(ThreadTree)malloc(sizeof(ThreadNode));
		T->data=x;
		T->lchild=T->rchild=NULL;
	}
	else {
		if(x>T->data){
			T->rchild=Creat(T->rchild,x);
		}
		else{
			T->lchild=Creat(T->lchild,x);
		}
	}
}

ThreadNode *NextNode(ThreadNode *p){			//先序二叉树的后继 
	if(p->rtag==1) return p->rchild;
	else {
		if(p->lchild) return p->lchild;
		else return p->rchild;
	}
}
int main()
{
	int i,j,k;
	int a[10]={2,5,6,9,3,4,7,8,1,0};
	ThreadTree T=(ThreadTree)malloc(sizeof(ThreadNode));
	T->data=a[0];
	T->lchild=T->rchild=NULL;
	for(i=1;i<9;i++){
		T=Creat(T,a[i]);		
	}
	CreatPreThread(T);
	printf("%d",NextNode(T)->data);
	return 0;
}

后序线索二叉树

后序线索二叉树同中序线索二叉树实现基本一致,遍历的时候调一下顺序就可。

#include
#include
#define N 100
typedef int ElemType;
typedef struct ThreadNode{
	ElemType data;
	struct ThreadNode *lchild,*rchild;
	int ltag,rtag;		//左右线索 
}ThreadNode,*ThreadTree;
ThreadNode *pre=NULL;
void visit(ThreadNode *q){			
	if(q->lchild==NULL){
		q->lchild=pre;
		q->ltag=1;
	}
	if(pre&&pre->rchild==NULL){
		pre->rchild=q;
		pre->rtag=1;
	}
	pre=q;
}
void PostThread(ThreadTree T){		//边遍历边线索化 
	if(T){
		visit(T);
		if(T->ltag==0){				//防止左边为线索无限循环的问题 
			PostThread(T->lchild);		
		}
		PostThread(T->rchild);
	}
}
void CreatPostThread(ThreadTree T){	//线索化二叉树 
	pre=NULL;
	if(T){
		PostThread(T);
		if(pre->rchild==NULL){		//如果最后一点为空,给他加标记 
			pre->rtag=1;			
		}
	}
}
ThreadTree Creat(ThreadTree T,int x){
	if(!T){
		ThreadTree T=(ThreadTree)malloc(sizeof(ThreadNode));
		T->data=x;
		T->lchild=T->rchild=NULL;
	}
	else {
		if(x>T->data){
			T->rchild=Creat(T->rchild,x);
		}
		else{
			T->lchild=Creat(T->lchild,x);
		}
	}
}
ThreadNode *PreNode(ThreadNode *p){
	if(p->ltag==1) return p->lchild;
	else {
		if(p->rchild) return p->rchild;
		else return p->lchild;
	}
}
int main()
{
	int i,j,k;
	int a[10]={2,5,6,9,3,4,7,8,1,0};
	ThreadTree T=(ThreadTree)malloc(sizeof(ThreadNode));
	T->data=a[0];
	T->lchild=T->rchild=NULL;
	for(i=1;i<9;i++){
		T=Creat(T,a[i]);		
	}
	CreatPostThread(T);
	printf("%d",PreNode(T)->data);
	return 0;
}

你可能感兴趣的:(c语言,数据结构)