✍个人博客:https://blog.csdn.net/Newin2020?spm=1011.2415.3001.5343
📚专栏地址:PAT题解集合
📝原题地址:题目详情 - 1102 Invert a Binary Tree (pintia.cn)
🔑中文翻译:反转二叉树
📣专栏定位:为想考甲级PAT的小伙伴整理常考算法题解,祝大家都能取得满分!
❤️如果有收获的话,欢迎点赞👍收藏📁,您的支持就是我创作的最大动力💪
1102 Invert a Binary Tree
The following is from Max Howell @twitter:
Google: 90% of our engineers use the software you wrote (Homebrew), but you can't invert a binary tree on a whiteboard so fuck off.
Now it’s your turn to prove that YOU CAN invert a binary tree!
Input Specification:
Each input file contains one test case. For each case, the first line gives a positive integer N (≤10) which is the total number of nodes in the tree – and hence the nodes are numbered from 0 to N−1. Then N lines follow, each corresponds to a node from 0 to N−1, and gives the indices of the left and right children of the node. If the child does not exist, a
-
will be put at the position. Any pair of children are separated by a space.Output Specification:
For each test case, print in the first line the level-order, and then in the second line the in-order traversal sequences of the inverted tree. There must be exactly one space between any adjacent numbers, and no extra space at the end of the line.
Sample Input:
8 1 - - - 0 - 2 7 - - - - 5 - 4 6
Sample Output:
3 7 2 6 4 0 5 1 6 5 7 4 3 2 0 1
题意
给定一棵二叉树,第一行给定 N N N ,表示有 N N N 个结点,且结点编号为 0 ∼ N − 1 0\sim N-1 0∼N−1 。
接下来
N
N
N 行输入
0
∼
N
−
1
0\sim N-1
0∼N−1 个结点的左右孩子编号,空结点用 -
表示。
需要将这颗二叉树进行反转,然后输出反转后的二叉树的层序遍历和中序遍历结果。
思路
- 用哈希表来存储每个结点的左右孩子下标。
- 递归交换每个结点的左右孩子,由于是用哈希表存的,所以直接交换哈希表中的值即可。
- 利用宽搜得到层序遍历的结果,然后递归打印中序遍历结果。
代码
#include<bits/stdc++.h>
using namespace std;
const int N = 20;
int l[N], r[N], has_father[N];
int q[N];
int n;
//反转二叉树
void dfs_reverse(int u)
{
if (u == -1) return;
dfs_reverse(l[u]);
dfs_reverse(r[u]);
swap(l[u], r[u]);
}
//层次遍历
void bfs(int root)
{
int hh = 0, tt = 0;
q[0] = root;
while (hh <= tt)
{
int t = q[hh++]; //取出队头元素
if (l[t] != -1) q[++tt] = l[t]; //如果左孩子不为空,则加入队列
if (r[t] != -1) q[++tt] = r[t]; //如果右孩子不为空,则加入队列
}
cout << q[0];
for (int i = 1; i < n; i++) cout << " " << q[i];
cout << endl;
}
//中序遍历
void dfs(int u, int& k)
{
if (u == -1) return;
dfs(l[u], k); //递归左孩子
cout << u; //打印该结点
if (++k != n) cout << " "; //最后一个结点后不能有空格
dfs(r[u], k); //递归右孩子
}
int main()
{
//初始化
cin >> n;
memset(l, -1, sizeof l);
memset(r, -1, sizeof r);
//输入结点信息
for (int i = 0; i < n; i++)
{
char ln, rn;
cin >> ln >> rn;
if (ln != '-') l[i] = ln - '0', has_father[l[i]] = true;
if (rn != '-') r[i] = rn - '0', has_father[r[i]] = true;
}
//找出根结点
int root = 0;
while (has_father[root]) root++; //根结点是没有父结点的
dfs_reverse(root); //反转二叉树
bfs(root); //层次遍历
int k = 0;
dfs(root, k); //中序遍历
return 0;
}