利用先序和中序非递归恢复二叉树,并后序遍历输出

作业...

算法思想参考自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);
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值