当前位置: 代码迷 >> 综合 >> PTA甲级 1102 Invert a Binary Tree (25分)
  详细解决方案

PTA甲级 1102 Invert a Binary Tree (25分)

热度:64   发布时间:2024-02-27 08:44:04.0

强烈推荐,刷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是非常好用的.

然后就是节点除了 数据和左右节点外,还有层次和下标可以保存.

用空间可以换取代码的好写.

如果这篇文章对你有张帮助的话,可以用你高贵的小手给我点一个免费的赞吗

相信我,你也能变成光.

在这里插入图片描述

如果你有任何建议,或者是发现了我的错误,欢迎评论留言指出.

  相关解决方案