PAT_A1115
PAT甲级1115.
目录
A1115
题目
样例
输入:
9
25 30 42 16 20 20 35 -5 28
输出:
2 + 4 = 6
思路和坑点
思路:
主要的思路是先根据给出的序列建树,然后层序遍历统计每层节点个数和树的高度,这里提供两种思路解决:①为节点添加一个层数的成员变量,然后初始化根以后遍历过程中,每个节点根据父节点的层数更新自己所在的层数。②使用双指针跟踪每一层的最后一个节点,每层进行计数,每层统计结束后,更新计数数组和计数器以及层数。
坑点:
注意如何处理层数为1的情况,如果默认根为0层,则一个节点的时候需要特判。或者,根为1层,但是注意初始化每层节点个数的计数为0。
AC代码(节点存放层数信息)
#include<bits/stdc++.h>
using namespace std;
int layercnt[1003]={0}; //存放i层的个数,初始化为0,这样当最大高度为1时倒数第二层不会数组越界
typedef struct node{ //二叉树结点
int data;
int layer; //结点所在层
struct node *left,*right; //节点左右指针
}Node,*Tree;
void Insert(Node* &root,int x); //将节点插入二叉树中
int layorder(Node *root); //层序遍历获取树的高度
int main(){
#ifdef ONLINE_JUDGE
#else
freopen("1.txt", "r", stdin);
#endif
int n;
Tree root=NULL;
scanf("%d",&n);
for(int i=0;i<n;i++){ //读取一个数据插入树中
int temp;
scanf("%d",&temp);
Insert(root,temp);
}
int ml=layorder(root); //层序遍历获取树高,并按照要求输出
printf("%d + %d = %d",layercnt[ml],layercnt[ml-1],layercnt[ml]+layercnt[ml-1]);
return 0;
}
void Insert(Node* &root,int x){ //插入函数
if(root==NULL){ //空树直接初始化为根即可
root=new Node;
root->data=x;
return;
}
if(x<=root->data){ //根据题目要求递归调用插入
Insert(root->left,x);
}
else if(x>root->data){
Insert(root->right,x);
}
}
int layorder(Node *root){ //层序遍历算法
int ret=0; //返回值,表示树的最大高度,默认高度从1开始,初始化为0
queue<Node *> q;
q.push(root);
root->layer=1; //初始化根节点高度
while(!q.empty()){
Node *now=q.front();
q.pop();
if(now->left!=NULL){
now->left->layer=now->layer+1;
q.push(now->left);
}
if(now->right!=NULL){
now->right->layer=now->layer+1;
q.push(now->right);
}
layercnt[now->layer]++;
ret=max(ret,now->layer);//更新高度
}
return ret;
}
AC代码(使双指针标记层数增长)
#include<bits/stdc++.h>
using namespace std;
int layercnt[1003]={0}; //存放i层的个数,默认根为第一层,这样最大高度为1时,倒是第二层访问数组不会越界
typedef struct node{ //二叉树结点
int data;
struct node *left=nullptr,*right=nullptr; //节点左右指针
}Node,*Tree;
void Insert(Node* &root,int x); //将节点插入二叉树中
int layorder(Node *root); //层序遍历获取树的高度
int main(){
#ifdef ONLINE_JUDGE
#else
freopen("1.txt", "r", stdin);
#endif
int n;
Tree root=NULL;
scanf("%d",&n);
if(n==1){ //特判
printf("1 + 0 = 1");return 0;
}
for(int i=0;i<n;i++){ //读取一个数据插入树中
int temp;
scanf("%d",&temp);
Insert(root,temp);
}
int ml=layorder(root); //层序遍历获取树高,并按照要求输出
printf("%d + %d = %d",layercnt[ml],layercnt[ml-1],layercnt[ml]+layercnt[ml-1]);
return 0;
}
void Insert(Node* &root,int x){ //插入函数
if(root==NULL){ //空树直接初始化为根即可
root=new Node;
root->data=x;
return;
} //根据规则插入
if(x<=root->data) Insert(root->left,x);
else Insert(root->right,x);
}
int layorder(Node *root){ //层序遍历算法
int layer=1,count=0; //层数layer,每层计数器count
Node *lastail=root,*tail=root;//lastail记录上一层的结尾,tail实时更新,一直变为本层的结尾,都初始化为根
queue<Node *> q;
q.push(root);
while(!q.empty()){
Node *now=q.front();
q.pop();
count++; //本层计数
//如果孩子不空则入队,这里tail先更新,然后顺带入队,可以写成一句,赋值时从右往左
if(now->left!=nullptr) q.push(tail=now->left);
if(now->right!=nullptr)q.push(tail=now->right);
if(now==lastail){ //如果发现上一层已经统计完
layercnt[layer++]=count;//更新计数统计,并增加层数,为下一层做准备
count=0; //重置计数器
lastail=tail; //更新lasttial为下一层的最后一个节点
}
}
return layer-1; //返回最大层数,因为最后一层统计结束后layer自动+1,所以这里要先减去
}