线索化二叉树

  二叉树的遍历本质上是将一个复杂的非线性结构转换为线性结构,使每个结点都有了唯一前驱和后继(第一个结点无前驱,最后一个结点无后继)。对于二叉树的一个结点,查找其左右子女是方便的,其前驱后继只有在遍历中得到。为了容易找到前驱和后继,有两种方法。一是在结点结构中增加向前和向后的指针,这种方法增加了存储开销,不可取;二是利用二叉树的空链指针。

1.具体做法

图示:
在这里插入图片描述
代码:

typedef char  ElemType;
#define END  '#'
typedef enum{LINK = 0,THREAD = 1} PointerTag;
typedef struct BiThrNode
{
	BiThrNode *leftchild;
	BiThrNode *rightchild;
	PointerTag Ltag,Rtag;     //左右标记 
	ElemType data;
}BiThrNode,*BinaryThreadTree;

void MakeThread(BiThrNode *p,BiThrNode *&ptr)    //线索化 
{
	if(p != NULL)
	{
		MakeThread(p->leftchild,ptr);

		if(p->leftchild == NULL)
		{
			p->leftchild = ptr;
			p->Ltag = THREAD;
		}
		if(ptr != NULL && ptr->rightchild == NULL)
		{
			ptr->rightchild = p;
			ptr->Rtag = THREAD;
		}
		ptr = p;

		MakeThread(p->rightchild,ptr);
	}
}
void MakeThreadTree(BiThrNode *p)     //线索化二叉树 
{
	BiThrNode *ptr = NULL;
	MakeThread(p,ptr);
	ptr->Rtag = THREAD;    //线索化最后一个结点 ,注意形参的类型 
}

代码解释;
在这里插入图片描述

2.优势

(1)利用线索二叉树进行中序遍历时,不必采用堆栈处理,速度较一般二叉树的遍历速度快,且节约存储空间。
(2)任意一个结点都能直接找到它的前驱和后继结点
不足
(1)结点的插入和删除麻烦,且速度也较慢。
(2)线索子树不能共用。

3.注意事项
  1. 注意MakeThread函数的第二个参数,他是一个指针的引用。这样做的目的是为了让指针ptr在递归的过程中所发生的改变,能够影响到每一层栈帧。
  2. 要深刻理解递归调用代码运行轨迹,只有这样才能为用好递归提供先决条件
  3. 线索化的过程是对空指针的利用,千万不要改变原来指针的指向
  4. 看代码要深刻理解代码的思路,把我代码的运行轨迹,不要只看效果,那样只会增加莫名的感觉,没实际效果
  5. 看不懂,想不通,画图、画图、画图,重要的事情说三遍。
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值