二叉树的按层打印与ZigZag打印
题目描述:
给定一颗二叉树,分别实现按层和 ZigZag 打印二叉树。
ZigZag遍历: 意思是第一层从左到右遍历,第二层从右到左遍历,依次类推。
输入描述:
第一行输入两个整数 n 和 root,n 表示二叉树的总节点个数,root 表示二叉树的根节点。
以下 n 行每行三个整数 fa,lch,rch,表示 fa 的左儿子为 lch,右儿子为 rch。(如果 lch 为 0 则表示 fa 没有左儿子,rch同理)
输出描述:
先输出按层打印,再输出按ZigZag打印。
示例1
输入
8 1
1 2 3
2 4 0
4 0 0
3 5 6
5 7 8
6 0 0
7 0 0
8 0 0
输出
Level 1 : 1
Level 2 : 2 3
Level 3 : 4 5 6
Level 4 : 7 8
Level 1 from left to right: 1
Level 2 from right to left: 3 2
Level 3 from left to right: 4 5 6
Level 4 from right to left: 8 7
备注:
1 ≤ n ≤ 5 ∗ 1 0 5 1 \leq n \leq 5*10^5 1≤n≤5∗105
1 ≤ f a , l c h , r c h , r o o t ≤ n 1 \leq fa,lch,rch,root \leq n 1≤fa,lch,rch,root≤n
题解:
对于层次打印,因为需要分层输出,需要记录每层层最后进入队列的节点,如果队列中弹出的节点等于这个节点,则需要换行。
对于 ZigZag 打印,同样需要记录每层最后一个节点。我们可以使用双端队列进行处理:
- 从左到右过程:弹出队列头部节点,将节点的左儿子、右儿子先后压入队列的尾部;
- 从右到左过程:弹出队列尾部节点,将节点的右儿子、左儿子先后压入队列的首部;
注意:换行时,第一个进入队列的节点是下一层最后一个打印的节点。
代码:
#include <cstdio>
#include <queue>
#include <deque>
using namespace std;
const int N = 500010;
struct BST {
int val, lch, rch;
} bst[N];
int n, rt;
int fa, lch, rch;
void printByLevel() {
queue<int> q;
int last = rt;
int nLast = 0;
q.push(rt);
int level = 0;
printf("Level %d :", ++level);
while (!q.empty()) {
int t = q.front();
q.pop();
printf(" %d", bst[t].val);
if (bst[t].lch) {
q.push(bst[t].lch);
nLast = bst[t].lch;
}
if (bst[t].rch) {
q.push(bst[t].rch);
nLast = bst[t].rch;
}
if (t == last && !q.empty()) {
printf("\nLevel %d :", ++level);
last = nLast;
}
}
puts("");
}
void printZigZag() {
int last = rt;
int nLast = 0;
bool flag = true;
deque<int> dq;
dq.push_front(rt);
int level = 0;
int now;
printf("Level %d from left to right:", ++level);
while (!dq.empty()) {
if (flag) {
now = dq.front();
dq.pop_front();
if (bst[now].lch) {
dq.push_back(bst[now].lch);
if (!nLast) nLast = bst[now].lch;
}
if (bst[now].rch) {
dq.push_back(bst[now].rch);
if (!nLast) nLast = bst[now].rch;
}
} else {
now = dq.back();
dq.pop_back();
if (bst[now].rch) {
dq.push_front(bst[now].rch);
if (!nLast) nLast = bst[now].rch;
}
if (bst[now].lch) {
dq.push_front(bst[now].lch);
if (!nLast) nLast = bst[now].lch;
}
}
printf(" %d", bst[now].val);
if (last == now && !dq.empty()) {
printf("\nLevel %d from ", ++level);
if (flag) printf("right to left:");
else printf("left to right:");
flag = !flag;
last = nLast;
nLast = 0;
}
}
}
int main(void) {
scanf("%d%d", &n, &rt);
while (n--) {
scanf("%d %d %d", &fa, &lch, &rch);
bst[fa].val = fa;
bst[fa].lch = lch;
bst[fa].rch = rch;
}
printByLevel();
printZigZag();
return 0;
}