线索化二叉树:
以线性方式遍历非线性二叉树;
即将二叉树中的所有结点进行逻辑意义上的“重排列”,使其可以以线性的方式访问每一个结点;
用链表的方式遍历二叉树,结点之间的逻辑关系有意义,而组织链表的逻辑关系缺毫无意义;
线索化方式一:
利用空的左指针域线索化二叉树(前序遍历)
//经典算法,利用结点中的空指针域,使其指向后继结点
void thread_via_left(BTreeNode* root, BTreeNode** pp)//前序遍历加一个额外的指针
{
if( (root != NULL) && (pp != NULL) )
{
if( *pp != NULL )
{
(*pp)->left = root;//指向当前结点
*pp = NULL;
}
if( root->left == NULL )//当前结点的左子树为空,指向当前结点
{
*pp = root;
}
thread_via_left(root->left, pp);
thread_via_left(root->right, pp);
}
}
线索化方式二:
利用线性表线索化二叉树(前序遍历)
//简单算法,利用线性表保存遍历二叉树的顺序
void thread_via_list(BTreeNode* root, SeqList* list)//前序遍历
{
if( (root != NULL) && (list != NULL) )
{
SeqList_Insert(list, (SeqListNode*)root, SeqList_Length(list));
thread_via_list(root->left, list);
thread_via_list(root->right, list);
}
}
利用结点空指针线索化的方法会破坏树的结构,利用结点空指针线索化二叉树之后不能够再恢复,这两个问题可以在树结点中加入一个线索化指针而得以解决,然而线索化指针的加入又会浪费内存空间,不够灵活。链表线索化方法不会破化树的结构,不需要时线索化时销毁链表。链表线索化方法可以很容易的以任何一种遍历顺序对二叉树进行线索化。链表线索化遍历,可使用先序遍历,中序遍历,后序遍历,层次遍历,而前者只能是先序遍历。