二叉树线索化示意图_二叉树的线索化算法思想详解

二叉树的线索化,这几天以来我很难掌握,今天终于想通了,哈哈,首先我们来看看二叉树线索化之后会变成什么样子,这里我们以图中的二叉树为例,图如下:

画的太糙,各位看官讲究着看吧- -。所谓二叉树的线索化,就是当一个节点的左右指针为空时,就让它的左右指针指向该节点的前驱或者后继(一般来说左指针指向前驱,右指针指向后继)。这里不论指向前驱或者后继,我们都应该线索化时,至少要明确两个节点指针的值,当前节点和当前节点的前驱/后继。这也是线索化的两种思路:

保存前驱:访问当前节点时若当前节点的左指针为空,则令左指针指向前驱,若前驱的右指针为空,则令前驱的右指针指向当前节点,代码描述如下:void visit(NODE* cur,NODE* &prev)//当前指针的前驱在当前指针访问时会改变,故传引用用来改变//prev

{

if(prev->right==NULL;

prev->right=cur;

if(cur->left==NULL)

cur->left=prev;

prev=cur;

}

这里我们要注意的是应该先进行访问,最后再改变prev的值。

保存后继:这种方法很难做到,并且个人觉得没有什么意义,因为在遍历整个数的过程中我们始终都会访问到一个节点的后继,若将要访问后继那我们如何保存到未来的东西,即使通过类似栈的数据结构通过压栈来强行访问,效率也是不高的,在此不推荐。

接下来献上c++完整的线索二叉树结构以及中序线索化过程,通过递归与非递归两种方式实现,其他的都大同小异。

节点类定义如下:

typedef char Datatype;

enum NodeType

{

LINK,

THERAD

};

struct TheardBinaryTreeNode

{

TheardBinaryTreeNode* _left;

TheardBinaryTreeNode* _right;

NodeType _leftTag;

NodeType _rightTag;

Datatype _data;

TheardBinaryTreeNode(const Datatype & data)

:_left(NULL)

, _right(NULL)

, _leftTag(LINK)

, _rightTag(LINK)

,_data(data)

{}

TheardBinaryTreeNode()

: _left(NULL)

, _right(NULL)

, _leftTag(LINK)

, _rightTag(LINK)

,_data((Datatype)0)

{}

};

中序线索化如下:void InTherad()

{

NODE* prev = NULL;

_InTherad(_root, prev);

//stacks;//借助栈来实现非递归的中序线索化

//NODE* cur = _root;

//NODE* prev = NULL;

//while (!s.empty()||cur)

//{

//while (cur)

//{

//s.push(cur);

//cur = cur->_left;

//}

//NODE* top = s.top();

//s.pop();

//if (top->_left == NULL&&top->_leftTag == LINK)

//{

//top->_left = prev;

//top->_leftTag = THERAD;

//}

//prev = top;

//if (top->_right == NULL&&top->_rightTag==LINK)

//{

//top->_rightTag = THERAD;

//if (!s.empty())

//top->_right = s.top();

//}

//else

//cur = top->_right;

//}

}

void _InTherad(NODE*root, NODE* &prev)//递归的中序线索化

{

if (root == NULL)

return;

_InTherad(root->_left, prev);

if (prev&&prev->_rightTag == LINK&&prev->_right == NULL)

{

prev->_right = root;

prev->_rightTag = THERAD;

}

if (root->_leftTag == LINK&&root->_left == NULL)

{

root->_leftTag = THERAD;

root->_left = prev;

prev = root;

}

_InTherad(root->_right,prev);

}

如有不足或者疑问希望留言提出。3Q -3-。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值