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.
1 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 NN ,表示有 N NN 个结点,且结点编号为 0 ∼ N − 1 0\sim N-10∼N−1 。
接下来 N NN 行输入 0 ∼ N − 1 0\sim N-10∼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; }