已知树的前序遍历和中序遍历,求后序遍历的方法(转)

/*    树中已知先序和中序求后序。
      如先序为:abdc,中序为:bdac .
      则程序可以求出后序为:dbca 。此种题型也为数据结构常考题型。
    算法思想:先序遍历树的规则为中左右,则说明第一个元素必为树的根节点,比如上例
中的a就为根节点,由于中序遍历为:左中右,再根据根节点a,我们就可以知道,左子树包含
元素为:db,右子树包含元素:c,再把后序进行分解为db和c(根被消去了),然后递归的
进行左子树的求解(左子树的中序为:db,后序为:db),递归的进行右子树的求解(即右
子树的中序为:c,后序为:c)。如此递归到没有左右子树为止。
关于“已知先序和后序求中序”的思考:该问题不可解,因为对于先序和后序不能唯一的确定
中序,比如先序为 ab,后序为ba,我只能知道根节点为a,而并不能知道b是左子树还是右子树
,由此可见该问题不可解。当然也可以构造符合中序要求的所有序列。

2004.12.5
*/

#include 
< stdio.h >
int  find( char  c, char  A[], int  s, int  e)  /* 找出中序中根的位置。 */
{
int i;
for(i=s;i<=e;i++)
      
if(A[i]==c) return i;
}

/* 其中pre[]表示先序序,pre_s为先序的起始位置,pre_e为先序的终止位置。 */
/* 其中in[]表示中序,in_s为中序的起始位置,in_e为中序的终止位置。 */
/* pronum()求出pre[pre_s~pre_e]、in[in_s~in_e]构成的后序序列。 */
void  pronum( char  pre[], int  pre_s, int  pre_e, char   in [], int  in_s, int  in_e)
{
char c;
int k;
if(in_s>in_e)    return ;                 /* 非法子树,完成。 */
if(in_s==in_e){printf("%c",in[in_s]); /* 子树子仅为一个节点时直接输出并完成。 */
                  
return ;
                  }

c
=pre[pre_s];                           /* c储存根节点。 */
k
=find(c,in,in_s,in_e);                 /* 在中序中找出根节点的位置。 */
pronum(pre,pre_s
+1,pre_s+k-in_s,in,in_s,k-1); /* 递归求解分割的左子树。 */
pronum(pre,pre_s
+k-in_s+1,pre_e,in,k+1,in_e); /* 递归求解分割的右子树。 */
printf(
"%c",c);                         /* 根节点输出。 */
}

main()
{
char pre[]="abdc";
char in[]="bdac";
printf(
"The result:");
pronum(pre,
0,strlen(in)-1,in,0,strlen(pre)-1);
getch();
}
 

// ..

已知二叉树的先序和中序求后序-转贴自CSDN 

 二叉树的根结点(根据三种遍历)只可能在左右(子树)之间,或这左子树的左边,或右子树的右边。 
如果已知先序和中序(如果是中序和后序已知也可以,注意:如果是前序和后序的求中序是不可能实现的),先确定这棵二叉树。 
步骤:
1 ,初始化两个数组,存放先序合中序。 
2 ,对比先序和中序,在中序忠查找先序的第一个元素,则在中序遍历中将这个元素的左右各元素分成两部分。即的左边的部分都在这个元素的左子树中,右边的部分都在右子树中。 
3 ,然后从从先序的第二个元素开始继续上面的步骤。 

如 先序:
1   2   3   4   5   6   7   8   9   10   11
后序:
3   2   5   4   1   7   9   8   11   10   6  


level 
1 1  
2 2   3  
3 3   4   7  
4 5   8  
5 9   10  
6 11  




这个太简单了,用个递归就可以,我到是有完整的代码,如下: 
//  tree.cpp : Defines the entry point for the console application. 
//  

#include 
" stdafx.h "  
#include 
" string.h "  

typedef 
struct  node 

char data; 
struct node *lchild,*rchild; 
}
BinNode; 
typedef BinNode 
* BinTree; 
BinNode 
* CreateNode( char  c) 

BinNode 
*n1=new BinNode; 
n1
->data=c; 
n1
->lchild=NULL; 
n1
->rchild=NULL; 
return n1; 
}
 
int  searchchar( char  c, char   * order) 

for(int i=0;i<strlen(order);i++

if(c==order[i]) 
return i; 

}
 
return -1
}
 

BinNode
*  CreateTree( char   * pre, char   * in

char c=pre[0]; 
char temppre[100]; 
char tempin[100]; 
char *p; 
int i=0
BinNode
* bnode; 
if(pre=='\0'
return NULL; 

memset(temppre,
0,100); 
memset(tempin,
0,100); 

bnode
=CreateNode(c); 
i
=searchchar(pre[0],in); 
if(i==-1
return 0
p
=in
strncpy(tempin,p,i); 
p
=pre; 
strncpy(temppre,p
+1,i); 
bnode
->lchild=CreateTree(temppre,tempin);//left 

memset(tempin,
0,100); 
memset(temppre,
0,100); 

p
=in+i+1
strncpy(tempin,p,strlen(
in)-i); 
p
=pre+i+1
strncpy(temppre,p,strlen(
in)-i); 
bnode
->rchild=CreateTree(temppre,tempin); //right 
return bnode; 
}
 

void  POSTORDER(BinNode  * t) 

if(t) /*二叉树t非空*/ 

POSTORDER(t
->lchild); /*后序遍历*t的左子树*/ 
POSTORDER(t
->rchild); /*后序遍历*t的右子树*/ 
printf(
"\t%c",t->data); /*访问结点*/ 
}
 
}
 

int  main( int  argc,  char *  argv[]) 

char preorder[100]; 
char inorder[100]; 

BinNode
* Head; 

do
printf(
"请输入前序序列\n"); 
scanf(
"%s",preorder); 
printf(
"请输入中序序序列\n"); 
scanf(
"%s",inorder); 
}
while(strlen(preorder)!=strlen(inorder)); 

Head
=CreateTree(preorder,inorder); 
printf(
"后序序列为:"); 
POSTORDER(Head); 
printf(
"\n"); 
// printf("%ld",strlen(readin)); 
return 0
}

转载:http://www.cppblog.com/abilitytao/archive/2009/03/17/76887.html
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值