求二叉树的最后2层的结点总数

PTA天梯模拟赛提交链接

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

二叉搜索树或者是一棵空树,或者是具有下列性质的二叉树:若它的左子树不空,则左子树上所有结点的值均小于或等于它的根结点的值若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值它的左、右子树也分别为二叉搜索树。将一系列数字按给定顺序插入一棵初始为空的二叉搜索树。

你的任务

是统计结果树中最下面 2 层的结点数。

输入格式:

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

输出格式:

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

输入样例:

9 25 30 42 16 20 20 35 -5 28

输出样例:

6

思路:

构建二叉树其实很简单,构建的过程中已经挂好的结点是无需再动。
对于每次输入的值
1.我们让它与根结点进行比较。
------a.如果它<=根结点,就去找该根结点的左孩子,倘若该根结点没有左孩子,那么就新建一个结点来充当该根结点的左孩子;倘若该结点有左孩子,那就把该左孩子看做一个根结点
,重复(1),直到把该值插入到二叉树中,然后再输入下一个值进行插入。
-------b如果>根结点,那就去找该根结点的右孩子,倘若该根结点没有右孩子,那么就新建一个结点来充当该根结点的右孩子;倘若该结点有右孩子,那就把该右孩子看做一个根结点,重复(1),直到把该值插入到二叉树中,然后再输入下一个值进行插入。

样例构建后的图
在这里插入图片描述

下面提供数组模拟结点的方法:

#include<stdio.h>
#include<string.h>
#include<algorithm>
#define INF 0x3f3f3f3f
using namespace std;
int a[1010]; 
int l[1010];//根据建二叉树的过程来存放下标,应该没啥规律吧 
int r[1010];//同理,只知道里面放的值的下标,不知道每一层的右子树都是什么值 
int cnt[1010];//cnt[i]表示深度为i的那一层有多少结点数 
int mx;//mx代表最深的深度,但是祖宗根结点那一层不算,所求的深度会少1 

void dfs(int root,int u,int deep)//0表示祖宗根结点 
{//root代表当前这颗树的根结点,u代表传入的下标值,deep表示此刻树的深	度
 // (一棵二叉树有很多树) 
	if(a[u]<=a[root])//输入的该值传给该结点的左孩子 
	{
		if(l[root]==INF)//当前根结点没有左孩子
		{
			l[root]=u;//创造一个结点来当左孩子,并把输入的值的下标放到结点里面 
			cnt[deep+1]++;//当前该树的根结点所处的深度的下一个深度多了一个结点 
			mx=max(mx,deep+1); //求最深度 
			return;//输入的该值已经放到二叉树里面 
		}
		else//当前根结点已有左孩子 
		{   //那把左孩子作为新的根结点继续向下搜索 
			dfs(l[root],u,deep+1);
			return;//执行完上一句说明输入的值已放入到二叉树中,那就可以返回,继续重新输入了 
		}
	}
	else//输入的该值传给该结点的右孩子 
	{
		if(r[root]==INF)
		{
			r[root]=u;
			cnt[deep+1]++;
			mx=max(mx,deep+1);
			return;
		}
		else
		{
			dfs(r[root],u,deep+1);
			return;
		}
	}
}
int main()
{
	int n,i;
	scanf("%d",&n);
	scanf("%d",&a[0]);
	if(n==1)
	printf("1");
	else
	{
		memset(l,INF,sizeof(l));//INF可认为相当于空 
		memset(r,INF,sizeof(r));
		for(i=1;i<n;i++)
		{
			scanf("%d",&a[i]);
			dfs(0,i,0);
		}
		printf("%d\n",cnt[mx]+cnt[mx-1]);
	}
//	printf("%d\n",mx);
	return 0;
}

下面再提供真正的创建结点的方法:我不太懂
方法类似,只是我不太懂指针

#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
using namespace std;
struct node 
{
	int data;
	int deep;
	struct node *lchild;
	struct node *rchild;
};//BSTNode,*BiTree;
//typedef long long ll; 
typedef node  BSTNode;//node是类型 
typedef node* BiTree;//node*是指针型类型 

int mx,s;

//   * 跟node还是跟build,此刻可理解为跟node,这样返回值的类型是地址 
BSTNode* build(BiTree root,int x,int p)//都有递归操作,与数组型类似 
{//root永远代表当前这棵树的根结点,x表示要存放的值,p表示深度 
	if(root==NULL)//用来创建结点的 
	{
		mx=max(mx,p);//求最大深度 
		BSTNode *root=(BSTNode*)malloc(sizeof(BSTNode));//需要创建一个结点 
		root->data=x;
		root->deep=p;
		root->lchild=root->rchild=NULL;
		return root;
	} 
	else 
	{
		if(x<=root->data)
			root->lchild=build(root->lchild,x,p+1);
		if(x>root->data)
			root->rchild=build(root->rchild,x,p+1);
		return root;
	}
}
void trave(BiTree root) 
{
	if(root!=NULL) 
	{
		if(root->deep==mx||root->deep==mx-1)
			s++;
		trave(root->lchild);
		trave(root->rchild);
	}
}
int main() 
{
	int n;
	scanf("%d",&n);
	mx=0;
	BiTree root=NULL;
	while(n--) 
	{
		int x;
		scanf("%d",&x);
		root=build(root,x,1);
	}
	s=0;
	trave(root);
	printf("%d\n",s);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Helinshan/article/details/110679739