线索二叉树与Morris遍历

本文详细介绍了二叉树线索化的过程和作用,通过中序遍历为例展示了如何构建线索二叉树,并提供了寻找节点前驱和后继的代码。接着,文章探讨了Morris遍历,这是一种不预先进行线索化的遍历方法,空间复杂度为O(1),时间复杂度为O(N)。通过对Morris遍历的原理和过程的解析,包括前序、中序和后序遍历的实现,读者可以深入理解这一高效的数据结构操作技巧。

一、二叉树线索化

对于一棵普通的二叉树,它的节点结构需要由两个指针域和一个数据域构成。而一棵树中必定存在一些指针域没有被使用到,这就造成了空间的浪费。

另一方面,我们经常用到二叉树的前、中、后序遍历,如果想求某种遍历中某个节点的前驱和后继节点,那就需要重新进行遍历。这无疑会造成时间的浪费。

所以为什么不把空闲的指针域利用起来,让其指向节点的前驱或后继呢?其实这就是线索二叉树的核心思想。

我们以中序遍历为例进行讲解。对于前面那棵二叉树,我们很容易得出它的中序遍历结果为:42513。但对于计算机来说,它只知道当前遍历到的节点cur,以及我们可以缓存下来的前一个遍历到的节点pre。

于是,计算机首先遍历到「4」这个节点

显然,这个节点的左右指针是空的,这两个指针域可以利用起来。但这个节点并没有前驱节点,而后继节点计算机并不知道是谁,所以这两个指针域还是只能指向空。

接下来遍历到「2」这个节点

虽然「2」节点的左右指针都不是空的,但它的前驱节点「4」的右指针还没有指向后继节点。而「4」的后继节点正是「2」节点。所以我们将「4」的右指针指向「2」

接下来指针遍历到了「5」节点

此时「5」节点的左指针为空,而且它的前驱我们知道是「2」,所以将左指针指向「2」

接下来指针遍历到「1」节点,它的前驱节点「5」的右指针为空,所以将「5」的右指针指向「1」

最后,指针遍历到「3」,它的左指针为空,所以将左指针指向「1」

至此,线索二叉树就构建完成了。但对于计算机来说,并不知道哪些指针是指向前驱或后继的指针,哪些指针是指向左右孩子的指针。所以我们还需要在二叉树节点的结构中引入两个bool变量,区分该指针是否是线索。

public class ThreadedBinaryTreeNode<T>
{
   
   
	public T data;
	public ThreadedBinaryTreeNode<T> left;
	public ThreadedBinaryTreeNode<T> right;
	public bool leftTag;
	public bool rightTag;
}

线索化的代码如下:

public void InThreading()
{
   
   
	InThreadingMethod(Head);
	// 处理遍历的最后一个节点
	if (_pre != null) _pre.RightTag = true;
}

private ThreadedBinaryTreeNode<T>? _pre;
private void InThreadingMethod(ThreadedBinaryTreeNode<T>? head)
{
   
   
	if(head == null) return;
	InThreadingMethod(head.Left);
	// 前驱线索
	if (head.Left == null)
	{
   
   
		head.Left = _pre;
		head.LeftTag = true;
	}
	// 后继线索
	if (_pre != null && _pre.Right == null)
	{
   
   
		_pre.Right = head;
		_pre.RightTag = true;
	}
	_pre = head;
	InThreadingMethod(head.Right);
}

完成线索化后,当我们需要查询某个节点的后继时,如果它有后继指针,那就可以直接返回后继指针指向的节点;否则就返回其右子树按中序遍历的第一个节点(最左节点)

public ThreadedBinaryTreeNode<T>? GetNext
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值