PTA 二叉搜索树的2层结点统计

二叉搜索树或者是一棵空树,或者是具有下列性质的二叉树:若它的左子树不空,则左子树上所有结点的值均小于或等于它的根结点的值;若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;它的左、右子树也分别为二叉搜索树。

将一系列数字按给定顺序插入一棵初始为空的二叉搜索树,你的任务是统计结果树中最下面 2 层的结点数。

输入格式:输入在第一行给出一个正整数 N (≤1000),为插入数字的个数。第二行给出 N 个 [−1000,1000] 区间内的整数。数字间以空格分隔。

输出格式:在一行中输出最下面 2 层的结点总数。

输入样例:

9

25 30 42 16 20 20 35 -5 28

输出样例:

6

一开始的分析:想着统计2层的结点树不就相当于先统计叶子结点树然后把该叶子结点去掉,再统计一次“叶子结点”,这样两次dfs后不就相当于统计到了两层的结点数了吗,但事实很快打脸。

下面附上错误算法下的半对代码:

#include<bits/stdc++.h>
using namespace std;
int cnt;
struct Tree
{
	int val;
	Tree* l;
	Tree* r;
};
void build(Tree* &t,int data)
{
	if(t==NULL)
	{
		t=new Tree();
		t->val=data;
		t->l=NULL;
		t->r=NULL;
		return;
	}
	if(data<=t->val) build(t->l,data);
	else build(t->r,data);
}
void dfs(Tree* &tt)
{
	if(tt!=NULL&&tt->l==NULL&&tt->r==NULL)
	{
		tt=NULL;
		cnt++;
		return;
	}
	else if(tt==NULL)
	return;
	dfs(tt->l);
	dfs(tt->r);
}
int main()
{
	int n;
	cin>>n;
	Tree* root=NULL;
	while(n--)
	{
		int x;
		cin>>x;
		build(root,x);
	}
	dfs(root);
	dfs(root);
	cout<<cnt;
    return 0;
}

很显然肯定是过不了的,能对一半已经是幸运!

而错误点在于,比如:

 这是在该算法下第一次dfs到第二次dfs树的情况,按这种算法,两层的结点数会变成4+2=6(黑色数字),而实际应该为5(绿色数字)!

下面为AC代码: 

#include<bits/stdc++.h>
using namespace std;
int mmax;
map<int,int>cnt;//cnt[第几层] = 结点个数
struct Tree
{
	int val;
	Tree* l;
	Tree* r;
};
void dfs(Tree* &t,int data,int level)
{
	if(t==NULL)
	{
		t=new Tree();
		t->val=data;
		t->l=t->r=NULL;
		cnt[level]++;
		mmax=max(mmax,level);
		return;
	}
	if(data<=t->val) dfs(t->l,data,level+1);
	else dfs(t->r,data,level+1);
}
int main()
{
	int n;
	cin>>n;
	Tree* root=NULL;
	while(n--)
	{
		int x;
		cin>>x;
		dfs(root,x,1);
	}
	cout<<cnt[mmax]+cnt[mmax-1];
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_61725823/article/details/123884184