二叉树的重建 已知前序 中序 求后序 递归的方法

算法介绍:

例如:先序遍历为DBACEGF,中序遍历为ABCDEFG。

递归的方法解决问题
先序串:DBACEGF,先序的第一个节点一定是根节点,这样我们就知道了根节点是D.
再看中序, 在中序串之中,根结点的前边的所有节点都是左子树中,ABCDEFG,所以D节点前面的ABC就是左子树的中序串。再看前续串 DBACEGF,由于左子树的节点是ABC,我们可以得到左子树的前续周游的串为: BAC.子树的前序串BAC,和中序串ABC ,我们就可以递归的把左子树给建立起来。 同样,可以建立起右子树。 


/*
描述:二叉树的重建 已知前序 中序 求后序
来源:http://www.cnblogs.com/lovell-liu/archive/2011/09/06/2169170.html
日期:20140820
*/
#include <iostream>
using namespace std;

struct NODE{
	NODE* pLeft;
	NODE* pRight;
	char chValue;
};

int GetPos(char* str, char ch)
	// 得到元素位于字符串的位置,就隐含了一个要求,字符不能重复
{
	for(int i=0; i<strlen(str); i++)
	{
		if(ch==str[i])
		{
			return i;
		}
	}
	return -1;
}
void Rebuild(char* pPreOrder, char* pInOrder, int nTreeLen, NODE** pRoot)
{
	if(*pRoot==NULL)
		return;
	*pRoot=(NODE*)malloc(sizeof(NODE));
	(*pRoot)->chValue = pPreOrder[0];
	int i=GetPos(pInOrder, pPreOrder[0]);
	if(i>=nTreeLen-1)
		(*pRoot)->pRight=NULL;
	if(i==0)
		(*pRoot)->pLeft=NULL;
	Rebuild(&pPreOrder[1], pInOrder, i, &(*pRoot)->pLeft);
	Rebuild(&pPreOrder[i+1], &pInOrder[i+1],nTreeLen-i-1, &(*pRoot)->pRight); 
}

void PostOrderRetrieval(NODE* root)    //后序遍历树
{
	if(root==NULL)
		return;
	if(root->pLeft !=NULL)
		PostOrderRetrieval(root->pLeft);
	if(root->pRight !=NULL)
		PostOrderRetrieval(root->pRight);
	printf("%c ", root->chValue);
}

int main()
{
	NODE** root;
	root = (NODE**)malloc(sizeof(NODE*));
	Rebuild("abdehcfgij", "dbheafcgji", 10, root);
	printf("后序遍历该树的结果为:\n");
	PostOrderRetrieval(*root);
	printf("\n");
	free(*root);
	free(root);
}


二叉树的遍历多例子,使用str输入  使用静态变量向树中添加

#include<stdio.h>
#include<stdlib.h>
#include<string>
#include <iostream>
using namespace std;
typedef struct node
{
	char num;
	node* left;
	node* right;
}node,*pnode;

static int len=-1;//全局的静态变量自动增加,确定加入的字符
void CreatTree(pnode* p,string str)//注意是node* *
{
	char c;
	node* tp;
	c=str[++len];
	
	if ('#'==c)
	{
		*p=NULL;
	}
	else
	{
		tp=new(node);
		tp->left=NULL;
		tp->right=NULL;
		tp->num=c;
		*p=tp;
		CreatTree(&(*p)->left,str);
		CreatTree(&(*p)->right,str);
	}

}
void DestroyTree(pnode *p)  
{ /* 初始条件: 二叉树T存在。操作结果: 销毁二叉树T */  
	if(*p) /* 非空树 */  
	{  
		if((*p)->left) /* 有左孩子 */  
			DestroyTree(&(*p)->left); /* 销毁左孩子子树 */  
		if((*p)->right) /* 有右孩子 */  
			DestroyTree(&(*p)->right); /* 销毁右孩子子树 */  
		free(*p); /* 释放根结点 */  
		*p=NULL; /* 空指针赋0 */  
	}  
}  
void travel(node *p)
{
	if (p)
	{
		travel(p->left);
		cout<<p->num<<" ";
		travel(p->right);
	}
}

int main() {
	string str;
	while (cin>>str)
	{
		len=-1;;
		node *root=NULL;
		CreatTree(&root,str);
		travel(root);
		cout<<endl;
		DestroyTree(&root);
	}
	
	return 1;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值