算法与数据结构第六次作业 渣五战的记忆力

最近复习到树的内容,之前的作业内容涉及到图论,之后再一起复习。

这题我当时自己做的时候完全没用到树,其实我这块学得比较差,自己也没什么信心。今天优秀作业的讲评,了解一下思路,回来参考了一下学霸的代码,自己敲了一遍。之后要多练习一些树相关的题。

先说思路:

       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>

树结构开始学得有点吃力,多刷题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值