二叉树的前、中、后序遍历在面试题中是否常见,可以说是非常基础而又非常实用的算法。
树的遍历
如图所示,前序遍历序列为:1 2 4 3 5
void dfs(int x)
{
if(x==0) return;
cout<<g[x].val<<" ";
dfs(g[x].l);
dfs(g[x].r);
}
中序遍历序列为:4 2 3 1 5
void dfs(int x)
{
if(x==0) return;
dfs(g[x].l);
cout<<g[x].val<<" ";
dfs(g[x].r);
}
后序遍历序列为:4 3 2 5 1
void dfs(int x)
{
if(x==0) return;
dfs(g[x].l);
dfs(g[x].r);
cout<<g[x].val<<" ";
}
容易看出三种遍历方法在代码中只有一行的区别,理解起来也非常简单。
已知两种遍历求第三种遍历序列
已知前序中序求后序:
int ask(int len,int pre,int in[])
{
for(int i=1;i<=len;i++)
if(in[i]==pre) return i;
}
void cal(int len,int pre[],int in[])
{
if(len<=0) return;
int root=ask(len,pre[1],in);
cal(root-1,pre+1,in);
cal(len-root,pre+root,in+root);
cout<<pre[1]<<" ";
}
signed main()
{
n=read();
for(int i=1;i<=n;i++) pre[i]=read();
for(int i=1;i<=n;i++) in[i]=read();
cal(n,pre,in);
}
已知后序中序求前序:
int ask(int len,int pre,int in[])
{
for(int i=1;i<=len;i++)
if(in[i]==pre) return i;
}
void cal(int len,int h[],int in[])
{
if(len<=0) return;
int root=ask(len,h[len],in);
cout<<h[len]<<" ";
cal(root-1,h,in);
cal(len-root,h+root-1,in+root);
}
signed main()
{
n=read();
for(int i=1;i<=n;i++) h[i]=read();
for(int i=1;i<=n;i++) in[i]=read();
cal(n,h,in);
}
已知前序后序求中序:
已知前后序遍历并不一定可以唯一确定一颗树,因此中序遍历不唯一。