Codeup Contest ID:100000612
题目描述
有一棵树,输出某一深度的所有节点,有则输出这些节点,无则输出EMPTY。该树是完全二叉树。
输入
输入有多组数据。
每组输入一个n(1<=n<=1000),然后将树中的这n个节点依次输入,再输入一个d代表深度。
输出
输出该树中第d层得所有节点,节点间用空格隔开,最后一个节点后没有空格。
样例输入
5
1 2 3 4 5
7
7
1 2 3 4 5 6 7
2
0
样例输出
EMPTY
2 3
思路
这题刚一拿到我还想着用vector容器来存当前结点的孩子结点,然后一遍BFS得到所有结点的层次,再根据层次输出所有结点。
但是懒癌让我发现这一题其实根本用不着用数组存(但是又得接受输入的那n个数,所以设个vector吧,节省点内存空间,输入完清了就好了),之所以这么说是因为题目说了这是一棵完全二叉树,也就是说只有最后一层的结点是满的或者半满的,其他层的结点都是满的,所以很容易就能通过数学公式算出来。
稍加列举就不难发现,深度为d(也就是第d层)的那一层第一个结点的编号是2d-1,d的下一层(也就是d+1层)的第一个结点编号是2d,因此,如果所问的不是最后一层,那么直接输出[2d-1, 2d-1]这个区间里的所有数即可,如果所问的是最后一层,那么就输出[2d-1, n]这个区间里的所有数。至于如何判断所问的层数是不是最后一层,很简单,看一看2d-1是不是小于等于n就行了,因为2d-1是当前层的最后一个元素(如果该层是满的话),如果它比n还大,那么显然当前层就是最后一层,如果小于等于n,那就说明不是最后一层(小于n),或者说是最后一层,但是是满结点的情况,即:满二叉树(等于n)。
代码
#include
#include
#include
#include
#include
using namespace std;
vector<int> temp;
int main(){
int n;
while(scanf("%d", &n) != EOF){
if(n==0) break;
for(int i=1;i<=n;i++){
int tmp;
scanf("%d", &tmp);//其实这里的输入没什么用
temp.push_back(tmp);
}
temp.clear();//直接清空掉算了
int d;
scanf("%d",&d);
int first = pow(2,d-1);//计算d层的首结点编号
int end = pow(2,d);//计算d+1层的首结点编号
if(first<=n&&end-1<=n){//如果d层的首元素小于等于n,说明该层结点完整
for(int i=first;i<=end-1;i++){//因为是完全二叉树,除了最后一层,其他肯定是满的
if(i==first) printf("%d", i);
else printf(" %d", i);
}
printf("\n");
}
else if(first<=n&&end-1>n){//该层即是最后一层
for(int i=first;i<=n;i++){
if(i==first) printf("%d", i);
else printf(" %d", i);
}
printf("\n");
}
else printf("EMPTY\n");
}
return 0;
}
题目描述
一棵树有n个节点,其中1号节点为根节点。
输入
第一行是整数n,表示节点数
后面若干行,每行两个整数a b,表示b是a的子节点。
输出
求这棵树的高度(根节点为第1层)
样例输入
5
1 2
1 3
3 4
3 5
样例输出
3
思路 中间改了不止一次的代码哈,一开始我确实是用静态树的方法来做的,但是因为时间超限的缘故,把能删的都删了,包括结构体里用来装孩子的vector容器,包括dfs函数,包括sort函数等等(因为我最初懒得在所有结点中寻找那个层次最大的结点,于是处理完所有结点的层次之后直接用sort函数给结构体数组来个从大到小的排序,最后直接输出第一个结点的层次就是我们要的答案了,但是后来想想看好像能直接int一个变量在处理的过程中实时更新高度的最大值就行了_(:з」∠)_)。 在经过一系列的删来删去之后,就得到了这串异常短小的代码…… 感觉树的遍历和之前学的DFS、BFS本质上是一样的,因为之前“岔路口”的概念,在一棵树上也同样能得到体现,不过非二叉树的话更多的用的是静态数组实现,而不是二叉树的动态链表实现(感觉用二叉树的链表来做先序中序后序遍历好方便的说),在这里只要记住先序中序后序遍历用DFS,层次用BFS遍历就好啦。 Codeup Contest ID:100000613 题目描述 样例输出 思路 题目描述 样例输出 思路 然后再对每个序列都建立一棵BST,然后对它进行先序(中序、后序也行)遍历,把遍历得到的序列存在一个nowPre的vector容器里(这里之所以用vector容器是为了对两个序列比较是否相等时,可以直接用“==”进行判断,而数组的话需要用for循环逐一比较),存放好了以后直接用“==”判断origin和nowPre是否相等,如果相等,则说明确实是同一棵BST,输出“YES”,如果不等,则不是同一棵BST,输出“NO”。 二叉查找树这一节的题目还是比较简单的哈,我觉得比较难的地方是BST的删除操作(书上的代码蛮长的,需要好好理解消化),其他的操作都和普通二叉树大体类似,只是在插入操作的时候加入了BST特有的性质,虽然可能用到的函数比较多,但是每个函数还是很简单的,就当是回顾性地练习一下二叉树的链表写法叭~
这题挺简单的,但是卡了我很久,一直都是时间超限50,原因在于我输入的判定写了while(1),然后终止循环的条件写的是b==n,结果一直超时(一直超时一直爽哈),后来改用for循环写成i=0到i
代码#include
小结
9.4 二叉查找树(BST)
问题 A: 二叉排序树
输入一系列整数,建立二叉排序数,并进行前序,中序,后序遍历。
输入
输入第一行包括一个整数n(1<=n<=100)。接下来的一行包括n个整数。
输出
可能有多组测试数据,对于每组数据,将题目所给数据建立一个二叉排序树,并对二叉排序树进行前序、中序和后序遍历。每种遍历结果输出一行。每行最后一个数据之后有一个空格。
样例输入1
2
2
8 15
4
21 10 5 39
2
2
2
8 15
8 15
15 8
21 10 5 39
5 10 21 39
5 10 39 21
这题很简单,就当是对BST的基本操作练习吧,主要流程就是把读入的数据建一棵BST,然后分别对这棵BST进行前序、中序、后序遍历即可。
代码#include
问题 B: 二叉搜索树
判断两序列是否为同一二叉搜索树序列
输入
开始一个数n,(1<=n<=20) 表示有n个需要判断,n= 0 的时候输入结束。
接下去一行是一个序列,序列长度小于10,包含(0~9)的数字,没有重复数字,根据这个序列可以构造出一颗二叉搜索树。
接下去的n行有n个序列,每个序列格式跟第一个序列一样,请判断这两个序列是否能组成同一颗二叉搜索树。
输出
如果序列相同则输出YES,否则输出NO
样例输入6
45021
12045
54120
45021
45012
21054
50412
0
NO
NO
YES
NO
NO
NO
思路很简单,对初始序列建立一棵BST,然后把它的先序序列(中序、后序也行)存放在一个叫origin的vector容器里。
代码#include
小结