1.后序+中序=》前序 转自:https://www.liuchuo.net/archives/2090
假设:
已知后序与中序输出前序(先序):
后序:3, 4, 2, 6, 5, 1(左右根)
中序:3, 2, 4, 1, 6, 5(左根右)
#include <cstdio> using namespace std; int post[] = {3, 4, 2, 6, 5, 1}; int in[] = {3, 2, 4, 1, 6, 5}; void pre(int root, int start, int end) {
//这里start和end是对in数组来说的,root是对于post数组的 if(start > end) return ; int i = start; while(i < end && in[i] != post[root]) i++; printf("%d ", post[root]); pre(root - 1 - end + i, start, i - 1);//左子树在后序遍历中根节点的位置 //root-(end-i)-1,最后还需要-1,先减去右子树中根节点的个数,再往前移动一个就是了。 pre(root - 1, i + 1, end);//这个start和end都是相对于中根遍历来说的。 } int main() { pre(5, 0, 5);//这里传进去的都是数组下标。 return 0; }
//需要多加复习。
2.前序+中序=》后序 转自:https://www.liuchuo.net/archives/2087
同样的道理,代码就可以理解了:
#include <cstdio> using namespace std; int pre[] = {1, 2, 3, 4, 5, 6}; int in[] = {3, 2, 4, 1, 6, 5}; void post(int root, int start, int end) { if(start > end) return ; int i = start; while(i < end && in[i] != pre[root]) i++; post(root + 1, start, i - 1); post(root + 1 + i - start, i + 1, end); printf("%d ", pre[root]); } int main() { post(0, 0, 5); return 0; }
下面是一个左子树为空的样例试验:
#include <cstdio> using namespace std; int pre[] = {1, 2, 3, 4}; int in[] = {1,3,2,4}; void post(int root, int start, int end) { if(start > end) return ; int i = start; while(i < end && in[i] != pre[root]) i++; post(root + 1, start, i - 1); //如果左子节点为空,那么此时在这个样例中就会调用: //post(1,0,-1);//那么就会直接返回了。 post(root + 1 + i - start, i + 1, end); printf("%d ", pre[root]); } int main() { post(0, 0, 3); return 0; }
3.层次+中序=》前序
参考:https://blog.csdn.net/qq_37494296/article/details/54971215
最重要的一点就是, 如何找到根节点?
在当前遍历的子数中,寻找对应的前序遍历节点序列最小的那个点就是根节点!
那么需要对前序遍历结果,即其出现的顺序做一个标记就可以了。
4.层次+中序=》后序
5.前序+后序能否?=》中序
转自:https://zhidao.baidu.com/question/242808856.html
不能,因为前序和中序本质上都是将父节点与子节点分离,但并不能指明左子树和右子树的界限,因此不能确定二叉树,可以用手画一个简单的,确实是不能判断左右子树。