**二叉搜索树的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;
}