已知后序与中序输出先序
后序的最后一个为根结点,令i在中序中找到该根结点,i的左边是左子树,右边是右子树
先序(根左右),先打印出当前根结点,然后遍历左子树,再遍历右子树
左子树在后序中的根结点为root – (end – i + 1),
即为当前根结点-(右子树的个数+1)
左子树在中序中的起始点start为start,末尾end点为i – 1
右子树的根结点为当前根结点的前一个结点root – 1,
右子树的起始点start为i+1,末尾end点为end
#include <bits/stdc++.h>
using namespace std;
static vector<int>PreInput;
static vector<int>InInput;
static vector<int>PostInput;
void PreOutput(int root,int start,int end){
if(start>end)return;
int i = start;
while(i < end && InInput[i] != PostInput[root])i++;//在中序遍历中找到根节点位置
cout << PostInput[root] << "->";
PreOutput(root - 1 - end + i,start,i - 1);
PreOutput(root - 1,i + 1,end);
}
已知先序与中序输出后序
先序第一个结点为根节点,令i在中序中找到该根结点,则i将中序分为两部分,后序(左右根),
先遍历左子树,再遍历右结点,然后打印根结点。
左子树再先序遍历中的根结点为root = root + 1,
右子树的根结点为root+(i-start+1),即为当前根结点-(左子树个数+1)
左子树在中序中的起始点start为start,末尾end为i-1
右子树的起始点start为i+1,末尾end为end
void PostOutput(int root,int start,int end){
if(start>end)return;
int i = start;
while(i < end && InInput[i] != PreInput[root])i++;
PostOutput(root + 1,start,i - 1);
PostOutput(root + (i - start + 1),i + 1,end);
cout << PreInput[root] << "->";
}
int main(){
int n,i;
cin >> n;
PostInput.resize(n);
InInput.resize(n);
PreInput.resize(n);
for(i=0;i<n;i++)cin >> PreInput[i];
for(i=0;i<n;i++)cin >> InInput[i];
for(i=0;i<n;i++)cin >> PostInput[i];
cout << "Based on known postorder traversal and inorder traversal to get preorder" << endl;
PreOutput(n-1,0,n-1);cout << endl;
cout << "Based on known preorder traversal and inorder traversal to get postorder" << endl;
PostOutput(0,0,n-1);cout << endl;
return 0;
}
完整源码
#include <bits/stdc++.h>
using namespace std;
static vector<int>PreInput;
static vector<int>InInput;
static vector<int>PostInput;
//已知后序与中序输出先序
/*后序的最后一个为根结点,令i在中序中找到该根结
点,i的左边是左子树,右边是右子树。先序(根左右),先打印出当前根结点,
然后遍历左子树,再遍历右子树。左子树在后序中的根结点为root – (end – i + 1),
即为当前根结点-(右子树的个数+1)。左子树在中序中的起始点start为start,
末尾end点为i – 1.右子树的根结点为当前根结点的前一个结点root – 1,
右子树的起始点start为i+1,末尾end点为end。*/
void PreOutput(int root,int start,int end){
if(start>end)return;
int i = start;
while(i < end && InInput[i] != PostInput[root])i++;//在中序遍历中找到根节点位置
cout << PostInput[root] << "->";
PreOutput(root - 1 - end + i,start,i - 1);
PreOutput(root - 1,i + 1,end);
}
//已知先序与中序输出后序
/*先序第一个结点为根节点,令i在中序中找到该根结点,则i将中序分为两部分,后序(左右根),
先遍历左子树,再遍历右结点,然后打印根结点。左子树再先序遍历中的根结点为root = root + 1,
右子树的根结点为root+(i-start+1),即为当前根结点-(左子树个数+1)。
左子树在中序中的起始点start为start,末尾end为i-1,右子树的起始点start为i+1,末尾end为end*/
void PostOutput(int root,int start,int end){
if(start>end)return;
int i = start;
while(i < end && InInput[i] != PreInput[root])i++;
PostOutput(root + 1,start,i - 1);
PostOutput(root + (i - start + 1),i + 1,end);
cout << PreInput[root] << "->";
}
int main(){
int n,i;
cin >> n;
PostInput.resize(n);
InInput.resize(n);
PreInput.resize(n);
for(i=0;i<n;i++)cin >> PreInput[i];
for(i=0;i<n;i++)cin >> InInput[i];
for(i=0;i<n;i++)cin >> PostInput[i];
cout << "Based on known postorder traversal and inorder traversal to get preorder" << endl;
PreOutput(n-1,0,n-1);cout << endl;
cout << "Based on known preorder traversal and inorder traversal to get postorder" << endl;
PostOutput(0,0,n-1);cout << endl;
return 0;
}