18959 二叉树的之字形遍历
时间限制:1000MS 代码长度限制:10KB
提交次数:0 通过次数:0
题型: 编程题 语言: G++;GCC
Description
题目来源:字节跳动测试题
给定一个二叉树,返回该二叉树的之字形层序遍历,(第一层从左向右,下一层从右向左,一直这样交替)
例如:
给定的二叉树是{3,9,20,15,7,#,#}
该二叉树之字形层序遍历的结果是
3
20 9
15 7
输入格式
一行字符串,只包含大写字母和#。
此处采用完全二叉树的顺序存储结构。
输出格式
若干行,之字形输出树的结点,每一行输出树的一层。
输入样例
ABC###D##
输出样例
A
C B
D
解题思路:
先看了看网上其他博主写的代码,感觉都比较高级(qaq,可能是自己太菜了)。其实一开始我看完这道题,想的是能不能用直接的方法做,比如说直接在字符数组内进行操作和输出。
那么顺着这一原始的思路,我先设了一个足够大的字符数组,将它的内存初始化为’#’。在输入字符串到这个数组之后,首先要找这个数组代表的树有几层,方法是先记录数组中最后一个大写字母的下标,然后根据这个下标算出这棵树的最大层数(此处我们可以利用一棵树在k层存在结点数 2的k次方-1的差 来算出最大层数k)。算出最大层数之后就简单了,设置变量i,从第一层遍历到第k层(注意我们一开始数组是从下标0开始存储的,因此每层的第一个结点在数组中的位置:start=2的i-1次方-1的差,每层的最后一个结点在数组中的位置为:end=2的i次方-2的差,想不懂的小伙伴可以在纸上演算一遍),最后设置flag变量来控制输出方向,如果flag为1,从start遍历到end,依次输出不是’#‘的字符,最后flag更新为0;如果flag为0,从end遍历到start,依次输出不是’#'的字符,最后flag更新为1。
ps:此方法适用于数据量较小的题目。
代码实现:
#include <cstdio>
#include <cstring>
#include <cmath>
char s[100000];
int main()
{
memset(s,'#',sizeof(s));//初始化 字符数组s 为'#'
scanf("%s",s);
int i,j,len=0,k;
for(i=0;i<100000;i++)//记录最后一个大写字母的下标
{
if(s[i]<='Z'&&s[i]>='A')
len=i;
}
len=len+1;//记得加1,因为数组是从0号为开始储存的
for(k=1;;k++)//寻找数组代表的数的最大层数
{
if(pow(2,k)>=len+1)//找到就溜
break;
}
int flag=1;//控制输出的方向(从左到右或从右到左)
for(i=1;i<=k;i++)//从第1层遍历第K层
{
int start=pow(2,i-1)-1;//第i层第一个结点下标
int end=pow(2,i)-2;//第i层最后一个结点的下标
if(flag==1)//从左到右输出
{
for(j=start;j<=end;j++)
{
if(s[j]!='#') printf("%c ",s[j]);
}
flag=0;//更新flag
}
else//从右到左输出
{
for(j=end;j>=start;j--)
{
if(s[j]!='#') printf("%c ",s[j]);
}
flag=1;//更新flag
}
printf("\n");//记得换行
}
return 0;
}
本人是一名2020级的大一生,求赞求互关qwq。