强烈推荐,刷PTA的朋友都认识一下柳神–PTA解法大佬
本文由参考于柳神博客写成
柳神的CSDN博客,这个可以搜索文章
柳神的个人博客,这个没有广告,但是不能搜索
还有就是非常非常有用的 算法笔记 全名是
算法笔记 上级训练实战指南 //这本都是PTA的题解
算法笔记
PS 今天也要加油鸭
题目原文
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
生词如下:
看不懂系列
需要翻译
Invert 转换
hence 因此(这个词不影响意思)
corresponds 对应
关键句子:
print in the first line the level-order, and then in the second line the in-order traversal sequences of the inverted tree
这个的意思是第一行输出层次遍历,第二行输出中序遍历.
他们输出的都是反转后的二叉树
思路如下:
这个反转,我是个懒人,我们可以直接在输入的时候,把左右字数换一下位置,这样输入的二叉树就直接是反转的二叉树了.
然后就层次,中序输出一下,就OK了.
PS:因为我用的是char存储的,写的时候,要注意格式的转换
代码如下:
#include<iostream>
#include<queue>
using namespace std;
struct node {char right;char left;
}Array[1030]; //2的10次方
void inorder(char root);
void LayerOrder(char root);
bool inorderfirst = false, levelfirst = false;
int main(void) {char root='0';int N, Root[20] = {0};scanf("%d", &N);for (int i = 0; i < N; ++i) {char c = getchar();scanf("%c %c", &Array[i].right, &Array[i].left);if(isdigit(Array[i].right)) Root[Array[i].right - '0'] = 1;if (isdigit(Array[i].left )) Root[Array[i].left - '0'] = 1;}for (int i = 0; i < N; ++i) if (Root[i] == 0) {root = i + '0';break;}LayerOrder(root);cout << endl;inorder(root);return 0;
}
void inorder(char root) {if (root == '-') return;inorder(Array[root-'0'].left);if (inorderfirst == false) inorderfirst = true;else printf(" "); printf("%c ", root);inorder(Array[root-'0'].right);
}
void LayerOrder(char root) {queue<char> q;q.push(root);while (!q.empty()) {char now = q.front();q.pop();if (levelfirst == false) levelfirst = true;else printf(" ");printf("%c ", now);if (Array[now - '0'].left != '-') q.push(Array[now - '0'].left);if (Array[now - '0'].right != '-') q.push(Array[now - '0'].right);}
}
柳神的思路:
分析:1. 反转二叉树就是存储的时候所有左右结点都交换。
2. 二叉树使用{id, l, r, index, level}存储每个结点的id, 左右结点,下标值,和当前层数~
3. 根结点是所有左右结点中没有出现的那个结点~
4. 已知根结点,用递归的方法可以把中序遍历的结果push_back到数组v1里面,直接输出就是中序,排序输出就是层序(排序方式,层数小的排前面,相同层数时,index大的排前面)
柳神的代码:
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;
struct node {int id, l, r, index, level;
} a[100];
vector<node> v1;
void dfs(int root, int index, int level) {//根左右if (a[root].r != -1) dfs(a[root].r, index * 2 + 2, level + 1);v1.push_back({ root, 0, 0, index, level });if (a[root].l != -1) dfs(a[root].l, index * 2 + 1, level + 1);
}
bool cmp(node a, node b) {if (a.level != b.level) return a.level < b.level;return a.index > b.index;
}
int main() {int n, have[100] = { 0 }, root = 0;cin >> n;for (int i = 0; i < n; i++) {a[i].id = i;string l, r;cin >> l >> r;if (l != "-") {a[i].l = stoi(l);have[stoi(l)] = 1;}else a[i].l = -1;if (r != "-") {a[i].r = stoi(r);have[stoi(r)] = 1;}else a[i].r = -1;}while (have[root] == 1) root++;dfs(root, 0, 0);vector<node> v2(v1);sort(v2.begin(), v2.end(), cmp);for (int i = 0; i < v2.size(); i++) {if (i != 0) cout << " ";cout << v2[i].id;}cout << endl;for (int i = 0; i < v1.size(); i++) {if (i != 0) cout << " ";cout << v1[i].id;}return 0;
}
学到的东西:
BFS和DFS是非常好用的.
然后就是节点除了 数据和左右节点外,还有层次和下标可以保存.
用空间可以换取代码的好写.
如果这篇文章对你有张帮助的话,可以用你高贵的小手给我点一个免费的赞吗
相信我,你也能变成光.
如果你有任何建议,或者是发现了我的错误,欢迎评论留言指出.