这种题一般有二种形式,共同点是都已知中序序列。如果没有中序序列,是无法唯一确定一棵树的,证明略。
一、已知二叉树的前序序列和中序序列,求解树。
1、确定树的根节点。树根是当前树中所有元素在前序遍历中最先出现的元素。
2、求解树的子树。找出根节点在中序遍历中的位置,根左边的所有元素就是左子树,根右边的所有元素就是右子树。若根节点左边或右边为空,则该方向子树为空;若根节点左边和右边都为空,则根节点已经为叶子节点。
3、递归求解树。将左子树和右子树分别看成一棵二叉树,重复1、2、3步,直到所有的节点完成定位。
二、已知二叉树的后序序列和中序序列,求解树。
1、确定树的根。树根是当前树中所有元素在后序遍历中最后出现的元素。
2、求解树的子树。找出根节点在中序遍历中的位置,根左边的所有元素就是左子树,根右边的所有元素就是右子树。若根节点左边或右边为空,则该方向子树为空;若根节点左边和右边都为空,则根节点已经为叶子节点。
3、递归求解树。将左子树和右子树分别看成一棵二叉树,重复1、2、3步,直到所有的节点完成定位。
举例说明:根据已知求解二叉树
中序序列 HLDBEKAFCG
后序序列 LHDKEBFGCA
1、在后序序列LHDKEBFGCA中最后出现的元素为A,HLDBEK|A|FCG
2、在后序序列LHDKEB中最后出现的元素为B,HLD|B|EK|A|FCG
3、在后序序列LHD中最后出现的元素为D,HL|D|B|EK|A|FCG
4、在后序序列LH中最后出现的元素为H,H|L|D|B|EK|A|FCG
5、在后序序列KE中最后出现的元素为E,H|L|D|B|E|K|A|FCG
5、在后序序列FGC中最后出现的元素为C,H|L|D|B|E|K|A|F|C|G
6、所有元素都已经定位,二叉树求解完成。
A / \ B C / \ / \ D E F G / \ H K \ L
代码如下:
5 #include < iostream >
6 #include < cstring >
7 using namespace std;
8
9 char pre[ 50 ] = " ABDHLEKCFG " ; // 前序序列
10 char mid[ 50 ] = " HLDBEKAFCG " ; // 中序序列
11 char post[ 50 ] = " LHDKEBFGCA " ; // 后序序列
12
13 typedef struct _Node
14 {
15 char v;
16 struct _Node * left;
17 struct _Node * right;
18 }Node, * PNode;
19
20 void PostTravelTree(PNode pn); // 树的后序递归遍历
21 void PreTravelTree(PNode pn); // 树的前序递归遍历
22 void PreMidCreateTree(PNode & pn, int i, int j, int len); // 利用前序中序序列创建树
23 void PostMidCreateTree(PNode & pn, int i, int j, int len); // 利用后序中序序列创建树
24 int Position( char c); // 确定c在中序序列mid中的下标,假设树的各个节点的值各不相同
25
26
27 int main()
28 {
29 PNode root1 = NULL, root2 = NULL;
30
31 PreMidCreateTree(root1, 0 , 0 , strlen(mid));
34 PostTravelTree(root1); cout << endl;
36 PostMidCreateTree(root2, strlen(post) - 1 , 0 , strlen(mid));
37 PreTravelTree(root2); cout << endl;
38
39 return 0 ;
40 }
41
42
43 int Position( char c)
44 {
45 return strchr(mid,c) - mid;
46 }
47
48
49
55 void PreMidCreateTree(PNode & pn, int i, int j, int len)
56 {
57 if (len <= 0 )
58 return ;
59
60 pn = new Node;
61 pn -> v = pre[i];
62 int m = Position(pre[i]);
63 PreMidCreateTree(pn -> left, i + 1 , j, m - j); // m-j为左子树字符串长度
64 PreMidCreateTree(pn -> right, i + (m - j) + 1 , m + 1 , len - 1 - (m - j)); // len-1-(m-j)为右子树字符串长度
65 }
66
67
68
73 void PostMidCreateTree(PNode & pn, int i, int j, int len)
74 {
75 if (len <= 0 )
76 return ;
77
78 pn = new Node;
79 pn -> v = post[i];
80 int m = Position(post[i]);
81 PostMidCreateTree(pn -> left, i - 1 - (len - 1 - (m - j)), j, m - j); // 注意参数:m-j左子树的长度,len-1-(m-j)右子树的长度
82 PostMidCreateTree(pn -> right, i - 1 , m + 1 , len - 1 - (m - j));
83 }
84
85
86 void PostTravelTree(PNode pn) // 后序递归遍历
87 {
88 if (pn)
89 {
90 PostTravelTree(pn -> left);
91 PostTravelTree(pn -> right);
92 cout << pn -> v << " " ;
93 }
94 }
95
96
97 void PreTravelTree(PNode pn) // 前序递归遍历
98 {
99 if (pn)
100 {
101 cout << pn -> v << " " ;
102 PreTravelTree(pn -> left);
103 PreTravelTree(pn -> right);
104 }
105 }