线索化存在的必要原因:对于一颗二叉树,遍历是一个经常性的操作,但是如果我们每次遍历时,都要通过递归或者通过栈实现二叉树的遍历,在遍历时需要进行很多判断,并且一定程度上浪费了一些空间和时间,因此我们考虑是否可以记录下其遍历时其”前驱”和”后继”。
方法:1.对每个二叉树节点增加两个字段”前驱”和”后继”来分别存储遍历过程中它的前一个节点位置和后一个节点位置,这种方式固然是方便,不过也不得不花费更多的空间来存储节点地址,这样一来,可能未能达到优化效果。
2.因为二叉树每个节点的左右子树可能不存在,指向其左右子树的指针为null,这个资源是完全可以被利用的,显然我们可以将节点左右子树指针为null的地方改为指向其”前驱”或者”后继”,但是这样我们就无法区分左右子树指针指向的是”子树”还是”前驱或后继”,所以我们要花费额外的两个bit来区分。
代码及代码说明
首先生成二叉树
typedef enum PointerTag{Link,Thread} PointerTag;//定义标签
typedef struct BiThrNode{
int data;
struct BiThrNode *lchirld,*rchild;
PointerTag LTag,RTag;
}BiThrNode;
//层序生成二叉树
BiThrNode* CreateTree(){
int arr[]={
1,2,3,4,5,6,7};
BiThrNode *root=(BiThrNode*)malloc(sizeof(BiThrNode));
root->data=1;
root->lchirld=root->rchild=NULL;
BiThrNode** con[7]={};
int r,l,idx;
con[0]=&(root->lchirld);
con[1]=&(root->rchild);