最近复习到树的内容,之前的作业内容涉及到图论,之后再一起复习。
这题我当时自己做的时候完全没用到树,其实我这块学得比较差,自己也没什么信心。今天优秀作业的讲评,了解一下思路,回来参考了一下学霸的代码,自己敲了一遍。之后要多练习一些树相关的题。
先说思路:
step1.先是建树,用一个结构体来记录每个结点的左儿子和右儿子。
step2.找到这棵树的根节点,我觉得这次优秀代码的这个部分是比较巧妙的。
参考了学霸的思路如下:
对每个点设置3个变量,0,1,-1.
对于-1,指的是永远不可能为根(当一个数为另一个的左儿子或者右儿子的时候)
对于1,指的是有可能为根,并且加到root里了。
对于0,指的是还没扫描到这个点。
最终得到的root即为root点。
step3.对这棵树进行先序遍历
<span style="font-size:18px;">#include <stdio.h>
#include <iostream>
using namespace std;
#define MAX 2001
struct T
{
int lson;
int rson;
}tree[MAX];
int flag[MAX];
int pre[MAX]={0};
int i=0;
void xxbl(int p)
{
if(p)
{
pre[i]=p;
i++;
xxbl(tree[p].lson);
xxbl(tree[p].rson);
}
}
int main()
{
int n,m,q,root=0,x,y,j;
memset(tree,0,sizeof(tree));
memset(flag,0,sizeof(flag));
scanf("%d%d%d",&n,&m,&q);
while(n--)
{
scanf("%d%d",&x,&y);
tree[x].lson=y;
if(flag[x]==0)//对于未确定是否为根的节点进行运算
{
root+=x;
flag[x]=1;
}
if(flag[y]==1)//对于认为可能是根节点,但又作为儿子出现的节点进行运算
{
root-=y;
flag[y]=-1;
}
flag[y]=-1;
}
while(m--)
{
scanf("%d%d",&x,&y);
tree[x].rson=y;
if(flag[x]==0)
{
root+=x;
flag[x]=1;
}
if(flag[y]==1)
{
root-=y;
flag[y]=-1;
}
flag[y]=-1;
}
//printf("%d",root);//这个是中间过程用来检测root是否正确
xxbl(root);
while(q--)
{
scanf("%d",&x);
if(tree[x].lson)
{
printf("<%d,1,",tree[x].lson);
}
else
{
for(j=0;pre[j]!=0;j++)
{
if(pre[j]==x)
break;
}
if(j==0)
printf("<%d,0,",x);
else
{
printf("<%d,0,",pre[j-1]);
}
}
printf("%d,",x);
if(tree[x].rson)
{
printf("1,%d>",tree[x].rson);
}
else
{
for(j=0;pre[j]!=0;j++)
{
if(pre[j]==x)
break;
}
if(pre[j+1]==0)
printf("0,%d>",x);
else
{
printf("0,%d>",pre[j+1]);
}
}
printf("\n");
}
return 0;
}
/*
3 2 6
5 4
3 2
7 6
3 5
5 7
2 3 4 5 6 7
*/
</span>
树结构开始学得有点吃力,多刷题。