线索二叉树

我们对一个二叉树进行中序排列后可以获得二叉树的中序序列。但这种信息只能在遍历的动态过程中才能获得。如果我们在每个节点中加入前驱和后继指针倒是可以直接保存下每个节点的前驱和后继。

但这样一来对于有n个节点的二叉树又增加了2n个指针,对空间的使用效率又降低了。如何解决这个问题?

二叉树的线索化


我们可以发现,在有n个节点的二叉树中必定有n+1个空指针,我们可以利用这些空指针来保存前驱和后继的信息。
对二叉树以某种次序遍历使其变为线索二叉树的过程叫做线索化。其规则如下:

1.若节点的左子树为空,则该节点的左指针指向其前驱节点。
2.若节点的右子树为空,则该节点的右指针指向其后继节点。

其中,指向前驱和后继的指针叫做线索。加上线索的二叉树叫做线索二叉树。
但我们如何区分一个线索二叉树的指针到底是指向前驱后继还是指向子树呢?为解决这一问题,我们在节点中添加标志位ltag和rtag。其定义如下:

1.ltag为0时,left指针指向左子树,为1时指向前驱节点。
2.rtag为0时,right指针指向右子树,为1时指向后继节点。


这样我们就能直接遍历线索二叉树了。

线索二叉树的遍历


//线索二叉树的声明
typedef enum ThreadTag{Link,Tread};

typedef struct _thrbinbode {
	Item data;
	struct _thrbinbode * left, * right;
	ThreadTag lTag, rTag;
}ThrBinNode;

//线索二叉树的遍历
void ThrBinTreeInOrder(ThrBinNode * pbtn, void(*pfun)(Item *))
{
	while (pbtn != NULL)
	{
		while (pbtn->lTag == Link)
			pbtn = pbtn->left;

		pfun(&pbtn->data);

		while (pbtn->rTag == Tread && pbtn->right != NULL)
		{
			pbtn = pbtn->right;
			pfun(&pbtn->data);
		}

		pbtn = pbtn->right;
	}
}
posted @ 2019-11-20 21:11  Sigmun  阅读(291)  评论(0)    收藏  举报