作业...
算法思想参考自http://blog.csdn.net/cwqbuptcwqbupt/article/details/6769222
//程序目的: 利用先序和中序序列,非递归地恢复二叉树
#include <iostream>
#include <cstring>
#include <stdlib.h>
using namespace std;
const int len = 7; //len定义为7 因为本例中先序序列只有7个
typedef struct BNode //树的结构体
{
char data;
struct BNode *Lchild;
struct BNode *Rchild;
}*BinaryTree,BinaryNode;
typedef struct //序列结构体,存储信息
{
char str; //记录字符
int num; //记录被读取的顺序
int mark; //记录是否已经被标记
int left; //是否有左右结点,有为1,无为0
int right;
}indata;
typedef struct //栈的结构体
{
BinaryTree bt[len]; //用来保存树结点指针
int left[len]; //分别用来保存对应结点是否有左右孩子
int right[len];
int top;
}Stack;
void RebuildTree(BinaryTree &bt);
void TravelFront(string front,indata data[len],BinaryTree &bt);
void ReLeftRight(indata data[len],int local);
void InitRootBinaryTree(BinaryTree &bt,indata data[len],int local,Stack &stack);
void LinkBinaryTree(indata data[len],int local, Stack &stack);
void PostTraverse(BinaryTree root);
int main()
{
BinaryTree bt=NULL;
RebuildTree(bt);
PostTraverse(bt);
system("pause");
return 0;
}
void RebuildTree(BinaryTree &bt)
{
//定义先序和中序
string front="ABDGCEF";
string mid ="DGBAECF";
indata data[len];
//记录中序的元素在先序所读取的顺序,并初始化
for (int i=0; i<len; i++)
{
for (int j=0; j<len; j++)
{
if (mid[i]==front[j])
{
data[i].str=mid[i];
data[i].num=j;
data[i].mark=0;
break;
}
}
}
TravelFront(front,data,bt); //开始
}
void TravelFront(string front,indata data[len],BinaryTree &bt)
{
//建立栈并初始化栈
Stack stack;
stack.top = -1;
//开始遍历建树
for (int i=0; i<len ; i++)
{
int local;
//此时local已经记录了元素位置
for (local=0; data[local].num != i; local++);
//判断该结点是否有左右结点
ReLeftRight(data,local);
//当i=0时候创建树根,赋值,并将其压进栈stack中
if (i==0)
{
InitRootBinaryTree(bt,data,local,stack);
}
else
{
LinkBinaryTree(data,local,stack);
}
}
}
void ReLeftRight(indata data[len],int local)//判断该结点是否有左右字树
{
int left_sum=0;
int right_sum=0;
data[local].mark=1;
//判断是否有左子树
for (int k=local;k>=0; k--)
{
if (k-1 !=0 &&data[k-1].mark==0 )
{
left_sum++;
}
else
{
k=0;
}
if (k==0)
{
if (left_sum==0)
{
data[local].left=0;
}
else
{
data[local].left=1;
}
}
}
//判断是否有右子树
for (int k=local;k<len; k++)
{
if (k+1 !=len &&data[k+1].mark==0 )
{
right_sum++;
}
else
{
k=len-1;
}
if (k==len-1)
{
if (right_sum==0)
{
data[local].right=0;
}
else
{
data[local].right=1;
}
}
}
}
void InitRootBinaryTree(BinaryTree &bt, indata data[len],int local,Stack &stack)
{
if (bt==NULL)
{
bt=(BinaryTree)malloc(sizeof(BinaryNode));
bt->Lchild=NULL;
bt->Rchild=NULL;
}
if (bt==NULL)
{
cout << "error";
exit(0);
}
else
{
//赋值
bt->data=data[local].str;
//压进栈
stack.top++;
stack.bt[stack.top]=bt;
stack.left[stack.top]=data[local].left;
stack.right[stack.top]=data[local].right;
}
}
void LinkBinaryTree(indata data[len],int local, Stack &stack)
{
//创建一个树结点
BinaryTree bt;
bt=(BinaryTree)malloc(sizeof (BinaryNode));
if (bt==NULL)
{
cout << "error " << endl;
exit (0);
}
else
{
//赋值
bt->data=data[local].str;
bt->Lchild=NULL;
bt->Rchild=NULL;
}
//利用栈顶元素将树连接
if (stack.left[stack.top]==1)
{
stack.bt[stack.top]->Lchild=bt;
stack.left[stack.top]=0;
}
else if (stack.right[stack.top]==1)
{
stack.bt[stack.top]->Rchild=bt;
stack.right[stack.top]=0;
}
//如果左右字树都为0,则弹出该树结点
if (stack.left[stack.top]+stack.right[stack.top]==0)
{
stack.top--;
}
//将当前结点压进栈
if (data[local].left+data[local].right !=0)
{
stack.top++;
stack.left[stack.top]=data[local].left;
stack.right[stack.top]=data[local].right;
stack.bt[stack.top]=bt;
}
}
void PostTraverse(BinaryTree root) //后序遍历输出
{
if (root == NULL)
return;
PostTraverse(root->Lchild);
PostTraverse(root->Rchild);
printf("%c",root->data);
}