408计算机考研--数据结构--线索化二叉树学习(C语言)

线索化二叉树学习(C语言)

一、线索二叉树的基本概念

​ 传统的二叉链表存储仅能体现一种父子关系,不能直接得到结点在遍历中的前驱或后继。我们知道,在含n个结点的二叉树中,有n+1个空指针。利用这些空指针来存放其前驱或后继的指针,这样就可以使得我们在遍历二叉树时可以像遍历单链表那样方便。引入线索二叉树正是为了加快查找结点前驱和后继的速度。(有三种线索化二叉树,分别是先序线索化二叉树、中序线索化二叉树以及后序线索化二叉树)

二、中序线索化二叉树创建、找前驱、找后继以及遍历

#include<stdio.h>
#include<stdlib.h>


//二叉树结构 
typedef struct ThreadNode{
	int data;
	struct ThreadNode *lchild,*rchild;//左右孩子指针 
	int ltag,rtag;//左右孩子线索标志 
}ThreadNode,*ThreadTree;
//中序遍历线索化二叉树的过程函数 
void InThread(ThreadTree &p,ThreadTree &pre){
	if(p!=NULL){
		InThread(p->lchild,pre);
		if(p->lchild==NULL){
			p->lchild=pre;
			p->ltag=1;
		}
		if(pre!=NULL&&pre->rchild==NULL){
			pre->rchild=p;
			pre->rtag=1;
		}
		pre=p;
		InThread(p->rchild,pre);
	}
}
//中序遍历建立中序线索二叉树 
void CreateInThread(ThreadTree T){
	ThreadTree pre=NULL;
	if(T!=NULL){
		InThread(T,pre);
		pre->rchild==NULL; 
		pre->rtag=1;
	}
}

//访问结点函数
void visit(ThreadTree T){
	printf("%d->",T->data);//打印结点数据 
}

//找到以p为根的子树第一个被中序遍历的结点
ThreadNode *FirstNode(ThreadNode *p){
	//循环找到最左下结点(不一定是叶结点)
	while(p->ltag==0){
		p=p->lchild;
	} 
	return p; 
} 
//在中序线索二叉树中找到结点p的后继结点
ThreadNode *NextNode(ThreadNode *p){
	//右子树中最左下结点
	if(p->rtag==0){
		return FirstNode(p->rchild);
	}else{
		return p->rchild;//rtag==1直接返回后继线索 
	}
}
//对中序线索二叉树进行中序遍历(利用线索实现的非递归算法) 
void InOrder(ThreadNode *T){
	for(ThreadNode *p=FirstNode(T);p!=NULL;p=NextNode(p)){
		visit(p);
	}
}

//找到以P为根的子树中,最后一个被中序遍历的结点
ThreadNode *LastNode(ThreadNode *p){
//循环找到最右下结点(不一定是叶结点)
 while(p->rtag==0){
 	p=p->rchild;
 } 
 return p;
} 
//在中序线索二叉树中找到结点p的前驱结点
ThreadNode *PreNode(ThreadNode *p){
	//左子树中最右下结点
	if(p->ltag==0){
		return LastNode(p->lchild);
	}else{
		return p->lchild;//ltag==1直接返回前驱线索 
	}
} 
//对中序线索二叉树进行逆向中序遍历
void ReInOrder(ThreadNode *T){
	for(ThreadNode *p=LastNode(T);p!=NULL;p=PreNode(p))
		visit(p);
} 

int main(){
	//测试结点数据 
	ThreadTree t1=(ThreadTree)malloc(sizeof(ThreadNode));
	ThreadTree t2=(ThreadTree)malloc(sizeof(ThreadNode));
	ThreadTree t3=(ThreadTree)malloc(sizeof(ThreadNode));
	ThreadTree t4=(ThreadTree)malloc(sizeof(ThreadNode));
	ThreadTree t5=(ThreadTree)malloc(sizeof(ThreadNode));
	
	t1->data=1;t1->lchild=t2;t1->rchild=t3;t1->ltag=t1->rtag=0;
	t2->data=2;t2->lchild=t4;t2->rchild=t5;t2->ltag=t2->rtag=0;
	t3->data=3;t3->lchild=NULL;t3->rchild=NULL;t3->ltag=t3->rtag=0;
	t4->data=4;t4->lchild=NULL;t4->rchild=NULL;t4->ltag=t4->rtag=0;
	t5->data=5;t5->lchild=NULL;t5->rchild=NULL;t5->ltag=t5->rtag=0;
	//线索化二叉树 
	CreateInThread(t1);
	//中序(顺序)打印 
	InOrder(t1); 
	printf("\n");
	//中序(逆序)打印
	ReInOrder(t1);
} 

三、前中后序线索化二叉树的找前驱、找后继比较

中序线索二叉树先序线索二叉树后序二叉树
找前驱×
找后继×
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值