// tmp.cpp : 定义控制台应用程序的入口点。
#include <stdio.h>
#include <malloc.h>
typedef struct Node
{
Node* lchild;
Node* rchild;
char bLchild;
char bRchild;
char data;
Node() :lchild(NULL), rchild(NULL), bLchild(1), bRchild(1){};
}Node;
void CreateTree(Node** root)//先序
{
char data;
scanf("%c", &data);
if (data == '#')
{
*root = NULL;
}
else
{
(*root) = (Node*)malloc(sizeof(Node));
(*root)->data = data;
printf("%c ", data);
CreateTree(&(*root)->lchild);
CreateTree(&(*root)->rchild);
}
}
//中序线索化
Node* pre = NULL;
//第一个节点 的左边节点为NULL,不存在pre
//最后一个节点 的右边节点为NULL,不存在后驱
void CreateThreadTree(Node* root)//中序遍历过程中, 前驱 后驱
{
if (root == NULL)
return;
CreateThreadTree(root->lchild);//左子树
//printf("%c ", root->data);
//此时该节点的前驱应该知道,后驱无法知道
if (root->lchild == NULL)
{//则填写前驱
root->lchild = pre;
root->bLchild = 0;
}
if (pre)//
{//pre不一定等于root->lchild
//printf("%c ", pre->data);
if (pre->rchild == NULL)//互相指引
{
pre->rchild = root;
pre->bRchild = 0;//前驱节点的后驱
}
}
pre = root;//本节点将变成下次节点的前驱
CreateThreadTree(root->rchild);
}
void MidOrderTree(Node* root)
{
if (root)
{
MidOrderTree(root->lchild);
printf("%c ", root->data);
MidOrderTree(root->rchild);
}
}
//中序遍历线索树
void MidOrderThreadTree(Node* root)
{
if (root == NULL)//何时终止呢?如果这样写,右子树为NULL,则停止后面的操作了,显然不合理
return;
//找到中序遍历的第一个节点,最左节点
//第一种方法,一直遍历左孩子,直到,不存在左孩子
//while (root->lchild)
//root = root->lchild;
while (root)
{
//第二种方法,无前驱
while (root->bLchild)//直到bLchild为0
root = root->lchild;
printf("%c ", root->data);
//不断的右边找后驱,直到找不到后驱
while (root->bRchild == 0 && root->rchild)
{
root = root->rchild;
printf("%c ", root->data);
}
//右边不是后驱,则必然是右孩子,所以指向右子树
root = root->rchild;
}
}
int main(int argc, const char* argv[])
{
Node* root;
CreateTree(&root);
printf("\n");
MidOrderTree(root);
printf("\n");
CreateThreadTree(root);//中序线索化
printf("\n");
//MidOrderTree(root);//不能再用原来的中序了,因为叶子节点的NULL,变成前驱和后驱了
//printf("\n");
MidOrderThreadTree(root);
return 0;
}