二叉树的链式存储时会有较多空间的浪费,当一颗有 n 个节点的二叉树存储共有2n个指针域,但是只有n-1个被用到,所以剩下的n+1个都会被浪费掉,因此可以想一种办法把剩余的空间利用起来,线索二叉树应运而生。
将二叉树重新定义如下每个节点为下列形式
lchild ltag data rtag rchild
其中:ltag=0 时lchild指向左子女;
ltag=1 时lchild指向前驱;
rtag=0 时rchild指向右子女;
rtag=1 时rchild指向后继;
所以结构体可定义为:
typedef enum{
Link,//枚举,第一个默认为0,后面的自动 +1
Thread
}PointerTag;
typedef struct Tree_Node{
char ch;
struct Tree_Node *left;
struct Tree_Node *right;
PointerTag ltag;
PointerTag rtag;
}Tree;
中序线索化
//中序线索化并实现打印
void midThread(Tree *tree){
if(tree){
midThread(tree->left);
printf("%c ",tree->ch);
if(!tree->left){
tree->ltag = Thread;
tree->left = pre;
}
if(!tree->right)
tree->rtag = Thread;
if(pre && pre->rtag == Thread) {
pre->right = tree;
}
pre = tree;
midThread(tree->right);
}
}
后序线索化
void end(Tree *tree){
if(tree){
end(tree->left);
end(tree->right);
printf("%c ",tree->ch);
if(!tree->left){
tree->ltag = Thread;
tree->left = pre;
}
if(!tree->right)
tree->rtag = Thread;
if(pre && pre->rtag == Thread)
pre->right = tree;
pre = tree;
}
}
完整代码如下
#include <stdio.h>
#include <stdlib.h>
typedef enum{
Link,
Thread
}PointerTag;
typedef struct Tree_Node{
struct Tree_Node *left;
struct Tree_Node *right;
char ch;
PointerTag ltag;
PointerTag rtag;
}Tree;
Tree *pre;
Tree *create(){
Tree *tree;
char ch;
scanf("%c",&ch);
if(ch == '*')
tree = NULL;
else{
tree = (Tree *)malloc(sizeof(Tree));
tree->ch = ch;
tree->left = create();
tree->right = create();
}
return tree;
}
void midThread(Tree *tree){
if(tree){
midThread(tree->left);
printf("%c ",tree->ch);
if(!tree->left){
tree->ltag = Thread;
tree->left = pre;
}
if(!tree->right)
tree->rtag = Thread;
if(pre && pre->rtag == Thread)
pre->right = tree;
pre = tree;
midThread(tree->right);
}
}
void end(Tree *tree){
if(tree){
end(tree->left);
end(tree->right);
printf("%c ",tree->ch);
if(!tree->left){
tree->ltag = Thread;
tree->left = pre;
}
if(!tree->right)
tree->rtag = Thread;
if(pre && pre->rtag == Thread)
pre->right = tree;
pre = tree;
}
}
int main(){
Tree *tree = create();
midThread(tree);
//end(tree);//调用时只能一个一个调用
}