对于给定前序和中序的重建方法。
1 前序的第一个元素一定是树的根节点,在中序集合中找到此元素,那么该元素的左面即为根的左子树,右面为右子树。
2 找到前序的第二个元素,重复上面的步骤。
自写程序的效率大概为 n*n/2 或最大的那个元素(这点很坑,斟酌改掉), 目前没发现更快的写法(自己写)
结果以连续内存的数组形式存储。
#include<cstdio> #include<iostream> using namespace std; int tree[200]; void reset(int f[],int l,int m[]) { int *t = tree; int vis[200]; int x; for(x=1;x<99;x+=3) { vis[x]=1; vis[x+1]=1; vis[x+2]=1; } for(;x<100;x++) vis[x]=1; int len=0,val=0; int temp; x=0; for(int i=0;i<l;i++) { len=0; temp = f[i]; x = x>temp?x:temp; val=vis[temp]; while(m[len++]!=temp); len--; for(int k=len-1;k>=0;k--) { temp = m[k]; if(vis[temp]<val) break; vis[temp]=val<<1; } for(int j=len+1;j<l;j++) { temp = m[j]; if(vis[temp]<val) break; vis[temp]=(val<<1)+1; } } t[1]=f[0]; for(int i=1;i<=x;i++) { if(vis[i]==1) continue; temp=vis[i]; t[temp]=i; } } int main() { int f[100]; int m[100]; int a; cin>>a; for(int i=0;i<a;i++) cin>>f[i]; for(int j=0;j<a;j++) cin>>m[j]; reset(f,a,m); return 0; } /* 8 1 2 4 7 3 5 6 8 4 7 2 1 5 3 8 6 9 1 2 4 8 9 5 3 6 7 8 4 9 2 5 1 6 3 7 */
其他情况待研究。