L3-016 二叉搜索树的结构 (30 分)(三种代码)

L3-016 二叉搜索树的结构 (30 分)

目录

L3-016 二叉搜索树的结构 (30 分)

代码1(段错误   数组开小了..开大一点能过)

代码2(dfs)

代码3 (AC)


【分析】

一开始建树做,想把它转换成完全二叉树,但是N=100的话,肯定数组是存不下的,所以导致最后一个测试点过不了段错误,只有27分..

数组开大点就可以了...数据比较水

代码1(段错误   数组开小了..开大一点能过)

#include<bits/stdc++.h>
using namespace std;

typedef struct node{
	struct node *lchild,*rchild;
	int val;
}node,*tree;
const int maxn=1e6+10;
int lv[maxn];
map<int,int>dep;
int n,cnt,cur,max_deep;

void insert(tree &T,int x,int deep)
{
	if(T==NULL)
	{
		T=new node();
		T->val=x;
		dep[x]=deep;
		max_deep=max(max_deep,deep);
		T->lchild=T->rchild=NULL;
		return;
	}
	if(x<T->val)insert(T->lchild,x,deep+1);
	else if(x>T->val)insert(T->rchild,x,deep+1);
}
void getLevel(tree &T)
{
	if(T==NULL)return;
	queue<tree>q;
	q.push(T);
	while(!q.empty())
	{
		tree t=q.front();
		q.pop();
		lv[cur++]=t->val;
		if(t->lchild!=NULL)q.push(t->lchild);
		else {t->lchild=new node();t->lchild->val=-1;q.push(t->lchild);}
		if(t->rchild!=NULL)q.push(t->rchild);
		else {t->rchild=new node();t->rchild->val=-1;q.push(t->rchild);}
		if(cur>pow(2,max_deep+1))break;
	}
}
int main()
{
	tree T=NULL;
	scanf("%d",&n);
	for(int i=0;i<n;++i)
	{
		int x;scanf("%d",&x);
		insert(T,x,0);
	}
	//cout<<"max_deep="<<max_deep<<endl;
	memset(lv,-1,sizeof(lv));
	getLevel(T);
	int q;scanf("%d",&q);
	getchar();
	while(q--)
	{
		string s;getline(cin,s);
		int x,y,f=0;
		if(s.find("root")!=string::npos)
		{
			sscanf(s.c_str(),"%d is the root",&x);
			if(dep.count(x) && x==lv[0])puts("Yes");
			else puts("No");
		}
		if(s.find("siblings")!=string::npos)
		{
			sscanf(s.c_str(),"%d and %d are siblings",&x,&y);
			if(dep.count(x) && dep.count(y))
			{
				for(int i=0;i<cur;++i)
					if((lv[i]==x && lv[i+1]==y)||(lv[i]==y && lv[i+1]==x))
					{
						puts("Yes");f=1;
						break;
					}
			}
			if(!f) puts("No");
		}
		if(s.find("parent")!=string::npos)
		{
			sscanf(s.c_str(),"%d is the parent of %d",&x,&y);
			if(dep.count(x) && dep.count(y))
			{	
				for(int i=0;i<cur;++i)
					if(lv[i]==x && (lv[i*2+1]==y || lv[2*i+2]==y))
					{
						f=1;puts("Yes");
						break;
					}
			}
			if(!f) puts("No");
		}
		if(s.find("left")!=string::npos)
		{
			sscanf(s.c_str(),"%d is the left child of %d",&x,&y);
			if(dep.count(x) && dep.count(y))
			{	
				for(int i=0;i<cur;++i)
					if(lv[i]==y && lv[i*2+1]==x)
					{
						f=1;puts("Yes");
						break;
					}
			}
			if(!f) puts("No");
		}
		if(s.find("right")!=string::npos)
		{
			sscanf(s.c_str(),"%d is the right child of %d",&x,&y);
			if(dep.count(x) && dep.count(y))
			{	
				for(int i=0;i<cur;++i)
					if(lv[i]==y && lv[i*2+2]==x )
					{
						f=1;puts("Yes");
						break;
					}
			}
			if(!f) puts("No");
		}
		if(s.find("same")!=string::npos)
		{
			sscanf(s.c_str(),"%d and %d are on the same level",&x,&y);
			if(dep.count(x) && dep.count(y))
			{	
				if(dep[x]==dep[y])puts("Yes");
				else puts("No");
			}
			else puts("No");
		}
	}
	return 0;
}

然后看了下小伙伴滴代码,直接深搜的,但是注意一下如果根节点的父亲是根节点的话,是No的,然后是30分...但是我觉得这个和建树一样啊数组a也会存不下的啊...为啥这个可以过呢??【然后我输入100个点从100到1降序输入,果然他是出不来结果的..】

因为数据水啊!!!

代码二:

#include<bits/stdc++.h>
using namespace std;

const int maxn=1e6+10;
int a[maxn];
map<int,int>mp;
int n;

void insert(int x,int pos)
{
//	cout<<"pos="<<pos<<endl;
	if(a[pos]==-1)
	{
		a[pos]=x;
		mp[x]=pos;
		return;
	}
	if(x<a[pos])insert(x,pos*2+1);
	else insert(x,pos*2+2);
}
int main()
{
	scanf("%d",&n);
	memset(a,-1,sizeof(a));
	for(int i=0;i<n;++i)
	{
		int x;scanf("%d",&x);
		insert(x,0);
	}
	int q;scanf("%d",&q);
	getchar();
	while(q--)
	{
		string s;getline(cin,s);
		int x,y,f=0;
		if(s.find("root")!=string::npos)
		{
			sscanf(s.c_str(),"%d is the root",&x);
			if(mp.count(x) && x==a[0])puts("Yes");
			else puts("No");
		}
		if(s.find("siblings")!=string::npos)
		{
			sscanf(s.c_str(),"%d and %d are siblings",&x,&y);
			if(mp.count(x) && mp.count(y) && mp[x] && mp[y] && (mp[x]-1)/2==(mp[y]-1)/2)puts("Yes");
			else puts("No");
		}
		if(s.find("parent")!=string::npos)
		{
			sscanf(s.c_str(),"%d is the parent of %d",&x,&y);
//			cout<<mp[y]-1<<endl;
			if(mp.count(x) && mp.count(y) && mp[y] && mp[x]==(int)(mp[y]-1)/2)puts("Yes");
			else puts("No");
		}
		if(s.find("left")!=string::npos)
		{
			sscanf(s.c_str(),"%d is the left child of %d",&x,&y);
			if(mp.count(x) && mp.count(y) && mp[y]*2+1==mp[x] && x<y)puts("Yes");
			else puts("No");
		}
		if(s.find("right")!=string::npos)
		{
			sscanf(s.c_str(),"%d is the right child of %d",&x,&y);
			if(mp.count(x) && mp.count(y) && mp[y]*2+2==mp[x] && x>y)puts("Yes");
			else puts("No");
		}
		if(s.find("same")!=string::npos)
		{
			sscanf(s.c_str(),"%d and %d are on the same level",&x,&y);
			if(mp.count(x) && mp.count(y) && (int)(log2(mp[x]+1))==(int)(log2(mp[y]+1)))puts("Yes");
			else puts("No");
		}
	}
	return 0;
}

还是百度了下大佬的代码...

不用定义结构体,直接用数组来做;l[i] & r[i]分别代表节点i的左右节点的下标;

deep数组存每个节点对应的index的深度;

mp存每个值的对应的下标

因为上面的数组的值对应的都是下标,所以要用map存一下;

这个就算100个降序读入数据,也是不会爆的...  但是这种思路我不太会想得到吧....

代码3(AC)

#include<bits/stdc++.h>
using namespace std;

const int maxn=110;
int a[maxn],l[maxn],r[maxn];
int pre[maxn],deep[maxn];
map<int,int>mp;
int n,q;
int root;

void insert(int &Root,int fa,int dep,int id)
{
//	cout<<l[Root]<<","<<r[Root]<<endl;
	if(Root==-1)
	{
		Root=id;//这里就是给l,r数组赋值;如果是-1那么会走这个if语句,然后赋值返回 
		pre[id]=fa;
		deep[id]=dep;
		return;
	}
	if(a[id]<a[Root])insert(l[Root],Root,dep+1,id);
	else insert(r[Root],Root,dep+1,id);
}
int main()
{
	scanf("%d",&n);
	memset(l,-1,sizeof(l));
	memset(r,-1,sizeof(r));
	root=-1;
	for(int i=1;i<=n;++i)
	{
		scanf("%d",&a[i]);
		insert(root,-1,1,i);
		mp[a[i]]=i;
	}
	scanf("%d",&q);getchar();
	while(q--)
	{
		string s;getline(cin,s);
		int x,y,f=0;
		if(s.find("root")!=string::npos)
		{
			sscanf(s.c_str(),"%d is the root",&x);
			if(mp.find(x)!=mp.end() && a[root]==x)f=1;
		}
		else if(s.find("siblings")!=string::npos)
		{
			sscanf(s.c_str(),"%d and %d are siblings",&x,&y);
			if(mp.find(x)!=mp.end() && mp.find(y)!=mp.end() && pre[mp[x]]==pre[mp[y]])f=1;	
		}
		else if(s.find("parent")!=string::npos)
		{
			sscanf(s.c_str(),"%d is the parent of %d",&x,&y);	
			if(mp.find(x)!=mp.end() && mp.find(y)!=mp.end() && pre[mp[y]]==mp[x])f=1;
		}
		else if(s.find("left")!=string::npos)
		{
			sscanf(s.c_str(),"%d is the left child of %d",&x,&y);	
			if(mp.find(x)!=mp.end() && mp.find(y)!=mp.end() && pre[mp[x]]==mp[y] && x<y)f=1;
		}
		else if(s.find("right")!=string::npos)
		{
			sscanf(s.c_str(),"%d is the right child of %d",&x,&y);	
			if(mp.find(x)!=mp.end() && mp.find(y)!=mp.end() && pre[mp[x]]==mp[y] && x>y)f=1;
		}else if(s.find("same")!=string::npos)
		{
			sscanf(s.c_str(),"%d and %d are on the same level",&x,&y);	
			if(mp.find(x)!=mp.end() && mp.find(y)!=mp.end() && deep[mp[x]]==deep[mp[y]])f=1;
		}
		if(f)puts("Yes");
		else puts("No");
	}
}

猜你喜欢

转载自blog.csdn.net/qq_38735931/article/details/88828149