线索二叉树——当标记位为0时怎么找到前驱和后继

        
 

        一次遍历(前序、中序、后序)后,可以很清楚地知道一个节点的前驱和后继分别是谁。如果不用线索,以后想知道必须再遍历一次,以后每次需要知道时,都必须再遍历一次,浪费了时间。因此引用了线索二叉树

        

        每个节点都有左右孩子指针的,也就是说左右孩子指针有时候是空闲的,不用白不用,那就把空间充分利用起来吧。约定:前驱装到空闲的(只有空闲的才敢用!)leftChild,后继装到空闲的rightChild里。但是这样又会有问题,我怎么知道你的孩子指针是不是空闲的,所以我们只能做出让步,加两个bool(或int)型的标志位,简单类型要比复杂类型的指针占空间少,借此节约了空间,当tag 是0代表装的孩子指针,是1代表装的前驱或后继指针,借以判断当前节点的左右孩子还是空闲。

指针为什么占用内存空间多一些:) 

(int是简单数据额类型,简单类型要比复杂类型的指针占空间少!注意:指针变量(在java里面是引用)里面存的是变量的内存地址,不是真的存的这个变量,占用的内存空间不是这个对象的大小。)

注意这里面节点和空闲左右孩子的数量:

1.一共有n个节点,则有2n个指针域

2.每一个孩子需要一条边和双亲相连,则有n-1条边用于存储左右孩子(根节点没有孩子)。

3.则有n+1个节点空闲

重点:

只有tag是1的时候才可以用来标定前驱和后继,是0的时候正常指向自己的左右孩子。

好了,下面解决刚才那个疑惑,如果不是1(也就是对应的节点不是空闲的)相应的前驱和后继应该怎么的到呢?下面看两个表格:

注意,是0的时候就是指向自己的两个孩子,不可能是Null

 

这张表很重要,希望你能看懂他!
表中解释了当不空闲的时候,也就是我们的前驱或后继指针没地放存放的时候,我们应该经过怎样的运算才可以依旧准确的找到相应节点的前驱和后继。 

并且求中序序列下的第一个节点、中序序列下的最后一个节点也不用遍历整个二叉树:

template<class T>
ThreadNode<T>* ThreadBinaryTree<T>::First(ThreadNode<T>* current) {
	//函数返回以current为根的中序线索二叉树中中序序列下的第一个节点
	ThreadNode<T>* ptr = current;
	while (0 == ptr->ltag) {
		ptr = ptr->leftChild;
	}
	return ptr;
}

template<class T>
ThreadNode<T>* ThreadBinaryTree<T>::Last(ThreadNode<T>* current) {
	//函数返回以current为根的中序线索二叉树中中序序列下的最后一个节点
	ThreadNode<T>* ptr = current;
	if (0 == ptr->rtag) {
		ptr = ptr->rightChild;
	}
	return ptr;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值