线索二叉树的创建

二叉树一般创建时用前序遍历法,线索化时用中序遍历

线索二叉树:指向前驱后继的指针称为线索,加上线索的二叉链表为线索链表。

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

typedef char ElemType;
//线索存储标志位
//Link(0):表示指向左右孩子的指针
//Thread(1):表示指向前驱后继的指针
typedef enum{Link,Thread} PointTag;

//二叉线索存储结点结构
typedef struct BitThrNode  
{
	ElemType data;                     
	struct BitThrNode *lchild,*rchild;
	PointTag LTag,RTag;
}BitThrNode,*BitThrTree;
//pre始终指向刚刚访问过的节点
BitThrTree pre;
//全局变量:始终指向刚刚访问过的节点

//创建一棵二叉树,约定用户遵照前序遍历的方式输入数据
void CreateBitThrTree(BitThrTree *T)
{
	ElemType ch;
	scanf("%c",&ch);
	if(ch=='#')
		*T=NULL;
	else
	{
		*T=(BitThrTree)malloc(sizeof(BitThrNode));
		(*T)->data=ch;
		(*T)->LTag=Link;
		(*T)->RTag=Link;
		
		CreateBitThrTree(&(*T)->lchild);
		CreateBitThrTree(&(*T)->rchild);
	}
}
//中序遍历进行二叉树线索化
void InThreading(BitThrTree p)
{
	if(p)
	{
		InThreading(p->lchild);//递归左孩子线索化
		if(!p->lchild)         //如果该节点没有左孩子,设置ltag为thread,并把lchild指向刚刚访问的节点
		{
			p->LTag=Thread;
			p->lchild=pre;
		}
		if(!pre->rchild)
		{
			pre->RTag=Thread;
			pre->rchild=p;
		}
		pre=p;
		InThreading(p->rchild);//递归右孩子线索化
	}
}

void InOrderThreading(BitThrTree *p,BitThrTree T)
{
	*p=(BitThrTree)malloc(sizeof(BitThrNode));//创建头结点
	
	(*p)->LTag=Link;
	(*p)->RTag=Thread;
	(*p)->rchild=T;
	
	if(!T)
	{
		(*p)->lchild=*p;//空树指向本身
	}
	else
	{
		(*p)->lchild=T;
		pre=*p;
		InThreading(T);
		pre->rchild=*p;
		pre->RTag=Thread;
		(*p)->rchild=pre;
	}
	
}
void visit(char c)
{
	printf("%c",c);
}
//中序遍历二叉树,非递归
void InOrderThaverse(BitThrTree T)//T是一个头指针了
{
	BitThrTree p;//根节点
	p=T->lchild;
	
	while(p!=T)
	{
		while(p->LTag==Link)
		{
			p=p->lchild;
		}
		visit(p->data);
		while(p->RTag==Thread&&p->rchild!=T)
		{
			p=p->rchild;
			visit(p->data);
		}
		p=p->rchild;
	}
	
}
void main()
{
	BitThrTree p,T=NULL;//p是头指针,T是根节点
	
	CreateBitThrTree(&T);
	InOrderThreading(&p,T);
	printf("中序遍历结果:\n");
	InOrderThaverse(p);
}

运行输入:前序输入:ABC##D##E#F##

运行输出:中序输出:CBDAEF


另一种编程:

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

typedef char elemtype;

typedef enum{normal,thread}node_type_t;
typedef struct node_s node_t;



typedef struct
{
	node_t *ptr;
	node_type_t type;
}node_ptr_t;

struct node_s
{
	elemtype data;
	node_ptr_t right,left;	
	int visited;
};
node_ptr_t *wanted=NULL;
node_t *pre=NULL;

node_t *new_node(elemtype data)
{
	node_t *node=(node_t *)malloc(sizeof(node_t));
	
	node->data=data;
	node->right.ptr=NULL;
	node->right.type=normal;
	node->left.ptr=NULL;
	node->left.type=normal;
	node->visited=0;
	
	return node;
}
void creat_tree(node_t **node)
{
	elemtype ch;
	scanf("%c",&ch);
	if(ch==' ')
		return;
	else
	{
		*node=new_node(ch);
		creat_tree(&((*node)->left.ptr));
		creat_tree(&((*node)->right.ptr));
	}
}

void travel_in_order(node_t *node,void (*cb)(node_t *))
{
	if(!node)
		return;
	else
	{
		travel_in_order(node->left.ptr,cb);
		cb(node);
		travel_in_order(node->right.ptr,cb);
	}
} 

void print(node_t *node)
{
	putchar(node->data);
}

void inthreading(node_ptr_t ptr)
{
	node_t *node=ptr.ptr;
	if(!node||ptr.type==thread)
	return;
	
	if(!node->left.ptr)//左孩子没有
	{
		node->left.ptr=pre;	
		if(pre)
		{
			node->left.type=thread;
		}
			
	}
	inthreading(node->left);
	if(wanted)
	{
		wanted->ptr=node;
		wanted->type=thread;		
		wanted=NULL;
	}
	if(!node->right.ptr)//右孩子没有
	{
		wanted=&(node->right);
	}
	pre=node;
	inthreading(node->right);
	
}
is_visit(node_t *node)
{
	return node->visited;
}
is_thread(node_ptr_t ptr)
{
	return ptr.type==thread ;
}
void visit_threading(node_t *node)
{
	print(node);
	node->visited=1;
}
void travel_with_threading(node_t *node,void cb(node_t *))
{
	travel_left:
	while(node->left.ptr&&!is_visit(node->left.ptr)&&!is_thread(node->left))
	{
		node=node->left.ptr;
	}
	cb(node);
	if(node->right.ptr||is_thread(node->right))
	{
		node=node->right.ptr;
		goto travel_left;
	}
	
	
}
void main()
{
	node_t *p;
	node_ptr_t pp;
		
	creat_tree(&p);
	
	pp.ptr=p;
	pp.type=normal;
	
	travel_in_order(p,print);
	printf("\n");
	inthreading(pp);
	
	travel_with_threading(p,visit_threading);
}


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
创建线索二叉树是一种对二叉树进行优化的数据结构。它的目的是为了加快二叉树的遍历速度。在传统的二叉树中,为了实现对二叉树的遍历,需要使用递归或者栈来实现。而线索二叉树通过添加线索,将二叉树的节点之间的遍历顺序进行编码,从而实现快速遍历。 在线索二叉树中,每个节点都有两个指针:左指针和右指针。在一棵二叉树中,如果一个节点没有左孩子,则将其左指针指向该节点的前驱节点。如果一个节点没有右孩子,则将其右指针指向该节点的后继节点。通过这样的线索指针,可以快速地找到一个节点的前驱和后继节点,进而实现对二叉树的快速遍历。 具体来说,在线索二叉树中,如果一个节点没有左孩子,则将其左指针指向其前驱节点;如果一个节点没有右孩子,则将其右指针指向其后继节点。通过这样的线索化过程,原本需要递归或者栈来实现的遍历过程,可以直接通过线索指针快速找到下一个需要遍历的节点,从而提高了遍历的效率。 总的来说,线索二叉树是一种优化的二叉树结构,通过添加线索指针,将二叉树的节点之间的遍历顺序进行编码,从而实现了对二叉树的快速遍历。它的设计思想主要是通过设置节点的线索指针指向前驱和后继节点,提高了遍历效率,减少了递归或栈的使用。这是一个在实际应用中常用的数据结构,可以广泛应用于二叉树遍历的场景中。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值