void Tree::inThread(node* p)
{
static node* pre = NULL;
//传入的前驱指针p一开始指向根节点A
if (p == NULL)
return;
//先通过不断对左子树的递归找到中序遍历的第一个节点
inThread(p->lchild);//左子树线索化
//----------------------------------------------------------------------------------
//如果p指向的左孩子为空就设置线索为1,然后左孩子指针指向前驱节点
if (p->lchild == NULL)//建立p的前驱线索
{
p->ltag = 1;
p->lchild = pre;
}
//如果pre不为空并且pre指向的右孩子为空,才会进行后驱寻找
if (pre != NULL && pre->rchild == NULL)//建立p的后驱线索
{
pre->rtag = 1;
pre->rchild = p;
}
pre = p;
//-----------------------------------------------------------------------------------------------
inThread(p->rchild);
}
//前序遍历生成树
void Tree::creat(node*& root)
{
char ch;
cin >> ch;//输入该节点的信息
if (ch == '#')//表示该节点为空
{
root = NULL;
}
else
{
root = new node;
root->data = ch; //生成一个节点,数据为ch
root->ltag = 0;
root->rtag = 0;
creat(root->lchild);
creat(root->rchild);
}
return;
}
#include<iostream>
using namespace std;
#include<conio.h>
struct node
{
char data;
int ltag;
node* lchild;
int rtag;
node* rchild;
};
class Tree {
private:
node* root;//指向根节点的头指针
public:
Tree() { creat(root); }//构造函数建立一个二叉树
~Tree() { relase(root); }//析构函数
void inThread(node* p);//遍历输出二叉树
node* getNode()
{
return root;
}
void display();
node* next(node* next);
private:
void creat(node*& root);//调用构造函数
void relase(node* root);//析构函数调用
};
//前序遍历生成树
void Tree::creat(node*& root)
{
char ch;
cin >> ch;//输入该节点的信息
if (ch == '#')//表示该节点为空
{
root = NULL;
}
else
{
root = new node;
root->data = ch; //生成一个节点,数据为ch
root->ltag = 0;
root->rtag = 0;
creat(root->lchild);
creat(root->rchild);
}
return;
}
void Tree::relase(node* root)
{
}
//中序线索链表建立
void Tree::inThread(node* p)
{
static node* pre = NULL;
//传入的前驱指针p一开始指向根节点A
if (p == NULL)
return;
//先通过不断对左子树的递归找到中序遍历的第一个节点
inThread(p->lchild);//左子树线索化
//----------------------------------------------------------------------------------
//如果p指向的左孩子为空就设置线索为1,然后左孩子指针指向前驱节点
if (p->lchild == NULL)//建立p的前驱线索
{
p->ltag = 1;
p->lchild = pre;
}
//如果pre不为空并且pre指向的右孩子为空,才会进行后驱寻找
if (pre != NULL && pre->rchild == NULL)//建立p的后驱线索
{
pre->rtag = 1;
pre->rchild = p;
}
pre = p;
//-----------------------------------------------------------------------------------------------
inThread(p->rchild);
}
//中序线索链表查找后继
node* Tree::next(node* next)
{
node* q = NULL;
if (next->rtag == 1)
{
//线索为1,表示右孩子指针指向后继节点
q = next->rchild;
}
else
{
//当前节点有右孩子,右孩子指针指向当前节点右孩子
//找到当前节点右子树最左下角的节点
q = next->rchild;
if (q->ltag == 0)//查找最左下角的节点,
//线索为0,表示
q = q->lchild;
}
return q;
}
//中序线索链表遍历
void Tree::display()
{
node* p;
if (root == NULL)
return;
p = root;
cout << "p->ltag=" << p->ltag << endl;
while (p->ltag == 0)//找到左子树最下面的左节点,itag==0表示左孩子指针指向左孩子节点,存在左孩子,而不是指向前驱节点
{
p = p->lchild;
}
//访问第一个节点
cout << p->data << endl;
//循环结束条件是当右孩子为空的时候结束
while (p->rchild != NULL)
{
//找到当前p的后继节点
p = next(p);
//输出后继节点的数据
cout << p->data << endl;
}
}
//测试---------------------
void test()
{
Tree t1;
cout << "打印结果如下" << endl;
//不能反回局部变量的引用以及局部变量开辟在堆区的引用
t1.inThread(t1.getNode());
cout << "---------------------" << endl;
t1.display();
}
int main()
{
test();
system("pause");
return 0;
}