数据结构——线索二叉树

        这章我们详细聊带线索的二叉树,首先在有一棵结点为 n 的二叉树的情况下,二叉树恒有 n+1 个空指针域;二叉树中有很多的空指针,可以让这些指针按照某种顺序指向下一个、前一个节点,这样在遍历时可以不用递归而可以使用循环遍历,可以提高树的遍历速度。那么问题来了,对二叉树进行线索化后,怎么才能区分一个指针是左右结点还是前驱后后继呢。其实这里的话我们可以在构造线索二叉树的时候添加一个数据项用于记录左右子树的标记,值为真表示指向后继,值为假指向子结点。

话不多说先来设计一下数据项:

typedef struct TreeNode
{
	int data;
	struct TreeNode *left;
	struct TreeNode *right;
	bool rflag;//为真时,right指向后继;否则指向右子树
}TreeNode;

下面来开始线索二叉树的各种运算操作:

创建结点

//创建结点
TreeNode *create_node(int data)
{
	TreeNode *node=malloc(sizeof(TreeNode));
	node->data=data;
	node->left=NULL;
	node->right=NULL;
	node->rflag=false;
	return node;
}

插入

void _insert(TreeNode **root,TreeNode *node)
{
	if(NULL==*root)
	{
		*root=node;
		return;
	}
	if(node->data<(*root)->data)
		_insert(&(*root)->left,node);
	else _insert(&(*root)->right,node);

}

//插入
void insert_tree(TreeNode **root,int data)
{
	_insert(root,create_node(data));	
}

中序

//中序
void midorder(TreeNode *root)
{
	if(NULL==root) return;
	midorder(root->left);
	printf("%d ",root->data);
	midorder(root->right);
}

按中序遍历创建线索(线索化)

//上一个结点
TreeNode *prev=NULL;

//创建线索 按照中序遍历
void create_clue(TreeNode *root)
{
	if(NULL==root) return;
	//左
	create_clue(root->left);
	
	//设置前驱
	/*if(NULL==root->left->)
	{
		root->left=prev;
		root->lflag=true;
	}*/

	//根
	//通过中序遍历找到root的上一个结点,如果该结点不为空,且右子树为空,则右子树指向root,也就是该结点的下一个结点
	if(NULL!=prev && NULL==prev->right)
	{
		prev->rflag=true;
		prev->right=root;
	}
	//如果不是,那么root就变成上一个结点
	prev=root;
	//右
	create_clue(root->right);
}

按照线索进行遍历

//按照线索进行遍历
void show_clue(TreeNode *node)
{
	while(node)
	{
		while(node->left) node=node->left;
		printf("%d ",node->data);
		while(node->rflag)
		{
			node=node->right;
			printf("%d ",node->data);
		}
		node=node->right;
	}
	printf("\n");
}

完毕,下面简单测试

int main(int argc,const char* argv[])
{
	TreeNode *root=NULL;
	for(int i=0;i<10;i++)
	{
		int data=rand()%100;
		insert_tree(&root,data);
	}

	midorder(root);
	printf("\n");
	create_clue(root);
	show_clue(root);
		
	return 0;
}

over

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值