在备考数据结构单元测试的过程中,无意间学到了c++中的姿势。大大的惊喜。原题为SWUST OJ 972题。
统计利用先序遍历创建的二叉树的宽度(0972)
Time limit(ms): 1000
Memory limit(kb): 10000
Submission: 1154
Accepted: 653
Accepted
Description
利用先序递归遍历算法创建二叉树并计算该二叉树的宽度。先序递归遍历建立二叉树的方法为:按照先序递归遍历的思想将对二叉树结点的抽象访问具体化为根据接收的数据决定是否产生该结点从而实现创建该二叉树的二叉链表存储结构。约定二叉树结点数据为单个大写英文字符。当接收的数据是字符”#”时表示该结点不需要创建,否则创建该结点。最后再统计创建完成的二叉树的宽度(是指二叉树每层节点数的最大值)。需要注意输入数据序列中的”#”字符和非”#”字符的序列及个数关系,这会最终决定创建的二叉树的形态。
Input
输入为接受键盘输入的由大写英文字符和”#”字符构成的一个字符串(用于创建对应的二叉树)。
Output
输出该用例对应的二叉树的宽度。
Sample Input
1 2 3 4 5 6 |
A## ABC#### AB##C## ABCD###EF##G### A##B## |
Sample Output
1 2 3 4 5 6 |
1 1 2 3 1 |
AC源代码:
#include<stdio.h>
#include<stdlib.h>
#include<queue>
#include<iostream>
using namespace std;
#define max(a,b) a>b?a:b
int i;
typedef struct node
{
char data;
struct node *lchild;
struct node *rchild;
}BTNode;int main()
{
void CreatTree(BTNode *&t,char str[]); //定义时要指出形参的数据类型,调用时才可以直接在相应位置用名字
int width(BTNode *t);
BTNode *t;
char str[100];
while(scanf("%s",str)!=EOF)
{
i=0;
CreatTree(t,str);
printf("%d",width(t));
}
return 0;
}
void CreatTree(BTNode *&t,char str[])
{
if(str[i]!=‘#‘)
{
t=(BTNode *)malloc(sizeof(BTNode));
t->data=str[i];
i++;
CreatTree(t->lchild,str);
CreatTree(t->rchild,str);
}
else
{
t=NULL;
i++;
}
}
int width(BTNode *t)
{
if(t==NULL)
return 0;
int mx=0,cnt;
BTNode *p;
queue<BTNode *>queA,queB; //queue模板类的定义
queA.push(t); //queue的基本操作之入队,将t元素接到队列的末端
while(!queA.empty())
{
cnt=0;
while(!queA.empty())
{
cnt++;
p=queA.front();
if(p->lchild!=NULL)
queB.push(p->lchild);
if(p->rchild!=NULL)
queB.push(p->rchild);
queA.pop(); //出队:如q.pop() 弹出队列的第一个元素,并不会返回元素的值;
}
mx=max(mx,cnt);
queA=queB;
while(!queB.empty())
queB.pop();
}
return mx;
}
涉及的知识:
queue模版类的定义在<queue>头文件中。
queue与stack模版非常类似,queue模版也需要定义两个模版参数,一个是元素类型,一个是容器类型,元素类型是必要的,容器类型是可选的,默认为dqueue类型。
定义queue对象的示例代码如下:
queue<int>q1;
queue<double>q2;
queue的基本操作有:
1.入队:如q.push(x):将x元素接到队列的末端;
2.出队:如q.pop() 弹出队列的第一个元素,并不会返回元素的值;
3,访问队首元素:如q.front()
4,访问队尾元素,如q.back();
5,访问队中的元素个数,如q.size();