二叉树的线索化

线索化的实质是将二叉链表中的空指针改为指向前驱或后继的线索,前驱和后继的信息是在遍历过程中才能得到,故线索化的过程即为在遍历过程中修改空指针的过程。

/*=============================*/
/*线索二叉树                   */
/*=============================*/
#include <stdio.h>
#include <stdlib.h>

typedef struct tree
{
	int data;
	int leftthread;
	int rightthread;
	struct tree *left;
	struct tree *right;
}treenode;

treenode *record;			//记录前驱和后继节点
/*=========================*/
/*递归创建二叉树           */
/*=========================*/
treenode *preorder_create(treenode *ptr)
{
	int data;

	printf("input data:");
	scanf("%d", &data);
	if(data == -1)
		return NULL;
	else
	{
		ptr = malloc(sizeof(treenode));
		
		ptr->data = data;
		ptr->leftthread = 0;
		ptr->rightthread = 0;
		ptr->left = preorder_create(ptr->left);
		ptr->right = preorder_create(ptr->right);
	}
	return ptr;
}
/*===============================*/
/*中序递归二叉树----线索化       */
/*===============================*/
treenode *in_threading(treenode *ptr)
{
	if(ptr != NULL)
	{
		in_threading(ptr->left);		//递归左子树线索化
		if(ptr->left == NULL)				//没有左子树
		{
			ptr->left = record;				//则指向前驱节点
			ptr->leftthread = 1;
		}
		if(record->right == NULL )			//前驱节点没有右子树
		{
			record->right = ptr;			//前驱右孩子指向后继节点
			record->rightthread = 1;
		}
		record = ptr;						//保持record指向ptr的前驱
		in_threading(ptr->right);		//递归右子树线索化
	}
}
/*===============================*/
/*二叉树线索化                   */
/*===============================*/
treenode *in_tread(treenode *root)		//root是树根节点
{
	treenode *head;		//head是头节点
	
	head = malloc(sizeof(treenode));
	head->data = 0;
	head->leftthread = 0;
	head->rightthread = 1;
	head->right = head;
	
	record = head;		//最初的前驱节点是头节点
	
	if(root == NULL)
		head->left = head;
	else
	{
		head->left = root;	
		in_threading(root);		//进行递归是从根节点开始,如果从头节点开始递归,则会陷入死循环
							//因为没有结束条件了,全部节点均不为NULL

		//递归结束后,最右边的节点的右子节点是NULL
		//需要手动连接到头节点
		record->right = head;
	}
	return head;
}
/*===============================*/
/*中序二叉线索树的中序遍历	     */
/*===============================*/
void tree_each(treenode *head)
{
	treenode *ptr = head->left;

	while(ptr != head)
	{
		while(ptr->leftthread == 0)
			ptr = ptr->left;
		printf("%d ", ptr->data);
		
		while(ptr->left != head && ptr->right == 1)
		{
			ptr = ptr->right;
			printf("%d ", ptr->data);
		}
		ptr = ptr->right;
	}
}
/*===============================*/
/*主函数			             */
/*===============================*/
int main()
{
	treenode *head;
	head = preorder_create(head);

	head = in_tread(head);
	
	tree_each(head);
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值