1、提出问题
在一些项目中需要频繁的遍历二叉树,但是二叉树的遍历比单链表的遍历复杂多了,并且递归总是会有额外开销。。。
那有没有一种方法,能像链表那样方便的快速遍历二叉树呢?
答案当然就是–线索化二叉树
2、线索化二叉树
- 线索化二叉树指的是将二叉树中的结点进行逻辑意义上的“重排列”,使其可以线性的方式访问每一个结点
- 二叉树线索化之后每个结点都有一个线性下标,通过这个下标可以快速访问结点,而不需要遍历二叉树
3、线索化方法一
这种方法和二叉树遍历法中的前序遍历很相似,甚至结果都是一样的!
算法思想:
算法实现:
/*
* 线索化
* 依据 空的左指针域 线索化
*/
void thread_btree_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_btree_left(root->left,pp);
thread_btree_left(root->right,pp);
}
}
4、线索化方法二
这种方法可结合二叉树遍历中的几种不同方法,来生成不同顺序的线性表。
算法思路:
算法实现:
/*
* 线索化
* 依据前序遍历,生成顺序表,进行线索化
*/
void thread_via_list(BTreeNode *root,Seqlist *list)
{
if((root != NULL)&&(list != NULL))
{
List_Insert(list,(SeqlistNode*)root,List_Length(list));
thread_via_list(root->left,list);
thread_via_list(root->right,list);
}
}
5、小结
- 利用结点空指针线索化的方法会破坏树的结构
- 利用结点空指针线索化二叉树之后不能够再恢复
- 这两个问题可以在树结点中加入一个线索化指针而得以解决
- 然而线索化指针的加入又会浪费内存空间,不够灵活
- 链表线索化方法不会破化树的结构,不需要线索化时销毁链表即可
- 链表线索化方法可以很容易的以任何一种遍历顺序对二叉树进行
线索化
6、完整源码下载
文件名:threadbtree-1.0.tar.gz
链接: http://pan.baidu.com/s/1hqivW1m 密码: p1cf
编译步骤:
0.1 解压缩:tar -zxvf threadbtree-1.0.tar.gz
0.2 进入目录:./configure
0.3 生成Seqlist:make
0.4 运行程序:./ThreadBtree