各大公司招聘每次笔试都碰到这种题,今天来把它说清楚.

三序中知道其中两个就可以推出第三个,但前提是我们必须知道中序.因为:

先序和后序给我们提供的信息是一样的--告诉我们谁是根节点

中序则告诉我们左右子树在哪儿

例:已知先序为eacbdgf,中序为abcdefg,求后序

由先序我们知道e为根节点,我们在中序中把左右子树括起来 --(abcd)e(fg)

同样对左子树abcd进行分析,先序为acbd,中序为abcd.--a(bcd)

递归下去就可以了

后序为bdcafge

代码实现上述例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
 
//定义二叉树的节点
typedef  struct  node{
     char  data;
     struct  node* left;
     struct  node* right;
}NODE;
//后根遍历打印二叉树
void  postTrav(NODE* root){
     //遍历左子树
     if (root->left!=NULL)
         postTrav(root->left);
     //遍历右子树
     if (root->right!=NULL)
         postTrav(root->right);
     //输出本节点
     printf ( "%c" ,root->data);
}
//根据前序和中序建立二叉树
void  buildTree( char * pre, char * mid,NODE* root){
     int  len= strlen (pre);        //实际下先序序列和后序序列的长度是一样的
     //序列长度为0,说明上一级已经是叶子节点,返回
     if (len==0)
         return ;
     
     //返回先序的第一个元素在中序中出现的位置
     char * p= strchr (mid,pre[0]);
     int  pos=( int )(p-mid);
     
     //建设子树的根节点
     //先序中第一个元素作为本子树的根节点
     root->data=pre[0];
     
     if (pos!=0){         //当前节点的左子树是存在的
         NODE* left=(NODE*) malloc ( sizeof ( struct  node));
         root->left=left;
         //左子树根节点上的元素就是先序中的第2个元素
         left->data=pre[1];  
         char * left_pre=( char *) malloc (pos* sizeof ( char ));
         char * left_mid=( char *) malloc (pos* sizeof ( char ));
         //找到左子树的先序和中序
         strncpy (left_pre,pre+1,pos);
         strncpy (left_mid,mid,pos);
         //递归建立左子树
         buildTree(left_pre,left_mid,left);
     }
 
     if (pos!=len-1){     //当前节点的右子树是存在的
         NODE* right=(NODE*) malloc ( sizeof ( struct  node));
         root->right=right;
         //右子树根节点上的元素就是先序中的第pos+2个元素
         right->data=pre[pos+1];
         char * right_pre=( char *) malloc ((len-1-pos)* sizeof ( char ));
         char * right_mid=( char *) malloc ((len-1-pos)* sizeof ( char ));
         //找到右子树的先序和中序
         strncpy (right_pre,pre+pos+1,len-1-pos);
         strncpy (right_mid,mid+pos+1,len-1-pos);
         //递归建立右子树
         buildTree(right_pre,right_mid,right);
     }
}
//主函数
int  main(){
     printf ( "input number of elements:\n" );
     int  size=0;
     scanf ( "%d" ,&size);
     char * pre=( char *) malloc (size* sizeof ( char ));
     char * mid=( char *) malloc (size* sizeof ( char ));
     printf ( "input preorder:\n" );
     scanf ( "%s" ,pre);
     printf ( "input midorder:\n" );
     scanf ( "%s" ,mid);
     NODE* root=(NODE*) malloc ( sizeof ( struct  node));
     buildTree(pre,mid,root);
     printf ( "the postorder is:\n" );
     postTrav(root);
     printf ( "\n" );
     return  0;
}

由二叉树的先序中序推出后序(转)_子树

这里顺便再介绍几个C语言里面的函数

首先对于指针变量必须先初始化malloc后才能使用,比如在上面的main函数中你没有char* pre=(char*)malloc(size*sizeof(char));就来个scanf("%s",pre);会发生段错误.

第1个函数:

表头文件#include<string.h>

定义函数char * strchr (const char *s,int c);

函数说明strchr()用来找出参数s字符串中第一个出现的参数c地址,然后将该字符出现的地址返回。

返回值如果找到指定的字符则返回该字符所在地址,否则返回0。

#include<string.h>

main()

{

char *s="0123456789012345678901234567890";

char *p;p=strchr(s,'5');

printf("%d\n",p-s);

}

第2个函数:

表头文件#include <string.h>

定义函数char *strpbrk(const char *s,const char *accept);

函数说明strpbrk()用来找出参数s 字符串中最先出现存在参数accept 字符串中的任意字符。

返回值如果找到指定的字符则返回该字符所在地址,否则返回0。

#include <string.h>

main()

{

char *s="0123456789012345678901234567890";

char *p;

p=strpbrk(s,"a1 839"); /*1会最先在s字符串中找到*/

printf("%d\n",(p-s));

p=strpbrk(s,"4398");/*3 会最先在s 字符串中找到*/

printf("%d\n",(p-s));

}

第3个函数:

表头文件#include<string.h>

定义函数char * strncpy(char *dest,const char *src,size_t n);

函数说明strncpy()会将参数src字符串拷贝前n个字符至参数dest所指的地址。

前提是dest必须能够容纳下n个字符.

返回值返回参数dest的字符串起始地址。

#inclue <string.h>

main()

{

char a[30]="string(1)";

char b[]="string(2)";

printf("before strncpy() : %s\n",a);

printf("after strncpy() : %s\n",strncpy(a,b,6));

}

C语言里面没有substr这样的函数,截取子串的功能就是通过strncpy来实现的,比如在我们的代码中有:

strncpy(left_pre,pre+1,pos);

这就是从pre的第2个元素开始,截取pos个字符放到left_pre中

原文来自:博客园(华夏35度)http://www.cnblogs.com/zhangchaoyang 作者:Orisun

 

三序中知道其中两个就可以推出第三个,但前提是我们必须知道中序.因为:

先序和后序给我们提供的信息是一样的--告诉我们谁是根节点

中序则告诉我们左右子树在哪儿

例:已知先序为eacbdgf,中序为abcdefg,求后序

由先序我们知道e为根节点,我们在中序中把左右子树括起来 --(abcd)e(fg)

同样对左子树abcd进行分析,先序为acbd,中序为abcd.--a(bcd)

递归下去就可以了

后序为bdcafge

代码实现上述例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
 
//定义二叉树的节点
typedef  struct  node{
     char  data;
     struct  node* left;
     struct  node* right;
}NODE;
//后根遍历打印二叉树
void  postTrav(NODE* root){
     //遍历左子树
     if (root->left!=NULL)
         postTrav(root->left);
     //遍历右子树
     if (root->right!=NULL)
         postTrav(root->right);
     //输出本节点
     printf ( "%c" ,root->data);
}
//根据前序和中序建立二叉树
void  buildTree( char * pre, char * mid,NODE* root){
     int  len= strlen (pre);        //实际下先序序列和后序序列的长度是一样的
     //序列长度为0,说明上一级已经是叶子节点,返回
     if (len==0)
         return ;
     
     //返回先序的第一个元素在中序中出现的位置
     char * p= strchr (mid,pre[0]);
     int  pos=( int )(p-mid);
     
     //建设子树的根节点
     //先序中第一个元素作为本子树的根节点
     root->data=pre[0];
     
     if (pos!=0){         //当前节点的左子树是存在的
         NODE* left=(NODE*) malloc ( sizeof ( struct  node));
         root->left=left;
         //左子树根节点上的元素就是先序中的第2个元素
         left->data=pre[1];  
         char * left_pre=( char *) malloc (pos* sizeof ( char ));
         char * left_mid=( char *) malloc (pos* sizeof ( char ));
         //找到左子树的先序和中序
         strncpy (left_pre,pre+1,pos);
         strncpy (left_mid,mid,pos);
         //递归建立左子树
         buildTree(left_pre,left_mid,left);
     }
 
     if (pos!=len-1){     //当前节点的右子树是存在的
         NODE* right=(NODE*) malloc ( sizeof ( struct  node));
         root->right=right;
         //右子树根节点上的元素就是先序中的第pos+2个元素
         right->data=pre[pos+1];
         char * right_pre=( char *) malloc ((len-1-pos)* sizeof ( char ));
         char * right_mid=( char *) malloc ((len-1-pos)* sizeof ( char ));
         //找到右子树的先序和中序
         strncpy (right_pre,pre+pos+1,len-1-pos);
         strncpy (right_mid,mid+pos+1,len-1-pos);
         //递归建立右子树
         buildTree(right_pre,right_mid,right);
     }
}
//主函数
int  main(){
     printf ( "input number of elements:\n" );
     int  size=0;
     scanf ( "%d" ,&size);
     char * pre=( char *) malloc (size* sizeof ( char ));
     char * mid=( char *) malloc (size* sizeof ( char ));
     printf ( "input preorder:\n" );
     scanf ( "%s" ,pre);
     printf ( "input midorder:\n" );
     scanf ( "%s" ,mid);
     NODE* root=(NODE*) malloc ( sizeof ( struct  node));
     buildTree(pre,mid,root);
     printf ( "the postorder is:\n" );
     postTrav(root);
     printf ( "\n" );
     return  0;
}

由二叉树的先序中序推出后序(转)_子树

这里顺便再介绍几个C语言里面的函数

首先对于指针变量必须先初始化malloc后才能使用,比如在上面的main函数中你没有char* pre=(char*)malloc(size*sizeof(char));就来个scanf("%s",pre);会发生段错误.

第1个函数:

表头文件#include<string.h>

定义函数char * strchr (const char *s,int c);

函数说明strchr()用来找出参数s字符串中第一个出现的参数c地址,然后将该字符出现的地址返回。

返回值如果找到指定的字符则返回该字符所在地址,否则返回0。

#include<string.h>

main()

{

char *s="0123456789012345678901234567890";

char *p;p=strchr(s,'5');

printf("%d\n",p-s);

}

第2个函数:

表头文件#include <string.h>

定义函数char *strpbrk(const char *s,const char *accept);

函数说明strpbrk()用来找出参数s 字符串中最先出现存在参数accept 字符串中的任意字符。

返回值如果找到指定的字符则返回该字符所在地址,否则返回0。

#include <string.h>

main()

{

char *s="0123456789012345678901234567890";

char *p;

p=strpbrk(s,"a1 839"); /*1会最先在s字符串中找到*/

printf("%d\n",(p-s));

p=strpbrk(s,"4398");/*3 会最先在s 字符串中找到*/

printf("%d\n",(p-s));

}

第3个函数:

表头文件#include<string.h>

定义函数char * strncpy(char *dest,const char *src,size_t n);

函数说明strncpy()会将参数src字符串拷贝前n个字符至参数dest所指的地址。

前提是dest必须能够容纳下n个字符.

返回值返回参数dest的字符串起始地址。

#inclue <string.h>

main()

{

char a[30]="string(1)";

char b[]="string(2)";

printf("before strncpy() : %s\n",a);

printf("after strncpy() : %s\n",strncpy(a,b,6));

}

C语言里面没有substr这样的函数,截取子串的功能就是通过strncpy来实现的,比如在我们的代码中有:

strncpy(left_pre,pre+1,pos);

这就是从pre的第2个元素开始,截取pos个字符放到left_pre中