众所周知,树是一种非线性结构,二叉树有三种常见的遍历方式,分别是前序、中序、后序三种,可以按照某种遍历方式使其排列成线性结构,使的第一个节点有且只有一个后续节点,最后一个节点有且只有一个前继节点,其余节点均只有一个前驱和后续节点,常规做法可以考虑在树结构体中加入前驱和后续指针域,但遗憾的是空间开销大,这里我们采用的是用标记域代替指针域,由于n个结点有n+1个空指针域,这里采用如下的规定.
LTag,RTag分别为左右标记域.
LTag=0时,lchild为其左孩子 LTag=1时,lchild为其前驱
RTag=0时,rchild为其右孩子 RTag=1时,rchild为其后续
此外在建立线索二叉树时,必须首先申请一个头结点,使其与树的根节点建立关系,建立线索树后,还需建立遍历的最后一个节点与头节点的关系.
#include <iostream>
#include <stdio.h>
using namespace std;
enum Tag {Link,Thread} ;
typedef int DataType;
struct ThreadBinaryTree
{
Tag LTag,RTag;
DataType data;
ThreadBinaryTree *lchild,*rchild;
};
ThreadBinaryTree *pre;
ThreadBinaryTree* CreateTree() //先序建立二叉树
{
ThreadBinaryTree *temp=new ThreadBinaryTree;
DataType t;
cin>>t;
if(t==0)
{
temp=NULL;
}
else
{
temp->data=t;
temp->LTag=Link;
temp->RTag=Link;
temp->lchild=CreateTree();
temp->rchild=CreateTree();
}
return temp;
}
void InThread(ThreadBinaryTree *p) //线索化
{
if(p)
{
InThread(p->lchild);
if(!p->lchild)
{
p->LTag=Thread;
p->lchild=pre;
}
if(!p->rchild) p->RTag=Thread;
if(pre!=NULL&&pre->RTag==Thread)
{
pre->rchild=p;
}
pre=p;
InThread(p->rchild);
}
}
ThreadBinaryTree* ThreadTree(ThreadBinaryTree *t) //线索二叉树
{
ThreadBinaryTree *head=new ThreadBinaryTree;
head->LTag=Link;
head->lchild=t;
head->rchild=head;
pre=head;
InThread(t);
pre->RTag=Thread;
pre->rchild=head;
return head;
}
void TravelThreadBinaryTree(ThreadBinaryTree *t) //遍历线索二叉树
{
ThreadBinaryTree *current=new ThreadBinaryTree;
current=t->lchild;
while(current!=t)
{
while(current->LTag==Link)
current=current->lchild;
cout<<current->data<<" ";
while(current->RTag==Thread&&t->rchild!=t)
{
current=current->rchild;
cout<<current->data<<" ";
}
current=current->rchild;
}
}
int main()
{
cout<<"按照先序构造二叉树"<<endl;
ThreadBinaryTree *t=new ThreadBinaryTree;
ThreadBinaryTree *head=new ThreadBinaryTree;
t=CreateTree();
head=ThreadTree(t);
TravelThreadBinaryTree(head);
//system("pause");
return 0;
}