03-树3 Tree Traversals Again (25分)
分析
看了下视频解析,觉得除了常规的借助先序与中序遍历把这棵树重新构造出来再遍历外,视频中借助规律和递归分治法真的是很简洁。 主函数中,在题中可以明白,Push进去的是先序的内容,Pop出去的是中序的内容,这样遍历完成所有输入后,可以得到pre in两个代表先序与后序遍历的数组。 之后,关键是围绕着这两个数组找出后序post的顺序,我们发现一些规律: 先序遍历中:根一定是第一项 中序遍历中:根的左右分别代表左右子树 后序遍历中:根一定是最后一项 这样我们可以用递归的思想来做。 首先可以通过先序找到根节点,首先将后序的最后一项填成根节点。 之后通过一层在中序中的遍历,通过找到中序的根结点的方式,我们可以知道根的左右子树所代表的数目。 接着,通过递归法,控制变量数目(具体数学实现见下图) 直到n == 1时,一定知道只有一个根,与先序一样,赋值 再加上一个n==0防错
具体代码实现
#include <iostream>
#include <stack>
#include <string>
#define MAX 100
using namespace std
;
int pre
[MAX
],in
[MAX
],post
[MAX
];
void solve(int preL
,int inL
,int postL
,int n
)
{
if(n
== 0){
return;
}
if(n
== 1){
post
[postL
] = pre
[preL
];
return;
}
int i
;
int root
= pre
[preL
];
post
[postL
+n
-1] = root
;
for(i
=0;i
<n
;i
++){
if(in
[inL
+ i
] == root
)
break;
}
int L
=i
,R
=n
-i
-1;
solve(preL
+1,inL
,postL
,L
);
solve(preL
+L
+1,inL
+L
+1,postL
+L
,R
);
}
int main()
{
int n
,num
,i
=0,j
=0,k
=0;
cin
>> n
;
string str
;
stack
<int> stack
;
for(;k
<2*n
;k
++){
cin
>> str
;
if(str
== "Push"){
scanf("%d\n",&num
);
stack
.push(num
);
pre
[i
++] = num
;
}else{
num
= stack
.top();
stack
.pop();
in
[j
++] = num
;
}
}
solve(0,0,0,n
);
for(i
=0;i
<n
;i
++){
printf("%d",post
[i
]);
if(i
!= n
-1){
printf(" ");
}
}
return 0;
}