思路很直接,从根开始,递归地交换左子树和右子树,然后进行层序和后序遍历。后来能通过题目给的用例,但是提交后只通过最后一个测试点。而且有个地方很奇怪,在VS运行所给的用例,能输出正确答案,但是在PAT的测试区却不行,而且输出一些很奇怪的数字:
后来发现invertBinaryTree
函数非空情况未返回node指针(没写return),修改后AC。
经验:
- 出现奇怪的数字,有一种可能是本应该是有效数据却为空。
- 递归函数在开头处理特殊/终止情况,这里要考虑清楚,容易出错。
代码如下:
#include<iostream>
#include<vector>
#include<queue>
#include<stdio.h>
using namespace std;
struct node
{
int val;
node* left, * right;
};
//规范的后序遍历进行invert
void postorder_invert(node* root) {
if (root == NULL)return;
postorder_invert(root->left);
postorder_invert(root->right);
node* temp = root->left;
root->left = root->right;
root->right = temp;
}
node* invertBinaryTree(node* root) {
if (root == NULL) return NULL;
if (root->left == NULL && root->right == NULL) return root; //这一行其实多余,相当于提前处理,即使不提前处理,也会到root==NULL中去
root->left = invertBinaryTree(root->left);
root->right = invertBinaryTree(root->right);
node* temp = root->left;
root->left = root->right;
root->right = temp;
return root; //开始时的错误之处
}
vector<int> inorder;
void inorder_traversal(node* root) {
if (root == NULL)return;
else {
inorder_traversal(root->left);
inorder.push_back(root->val);
inorder_traversal(root->right);
}
}
//树的层序遍历
vector<int> levelTraversal(node* root) {
vector<int> ret;
if (root) {
queue<node*> q;
q.push(root);
while (!q.empty()) {
ret.push_back(q.front()->val);
if (q.front()->left) q.push(q.front()->left);
if (q.front()->right) q.push(q.front()->right);
q.pop();
}
}
return ret;
}
int main() {
int n;
cin >> n;
vector<node*> nodes(n);
for (int i = 0; i < n; i++) {
nodes[i] = (node*)malloc(sizeof(node));
nodes[i]->val = i;
nodes[i]->right = NULL;
nodes[i]->left = NULL;
}
vector<int> vec(n);
char c1, c2;
for (int i = 0; i < n; i++) {
cin >> c1 >> c2;
if (c1 != '-') {
nodes[i]->left = nodes[c1 - '0'];
vec[c1 - '0'] = 1;
}
if (c2 != '-') {
nodes[i]->right = nodes[c2 - '0'];
vec[c2 - '0'] = 1;
}
}
node* root;
int i = 0;
for (; i < n; i++)
if (vec[i] != 1)break;
root = nodes[i];
root = invertBinaryTree(root);
//postorder_invert(root);
vector<int> v = levelTraversal(root);
for (int i = 0; i < n; i++) {
cout << v[i];
if (i != n - 1)cout << " ";
}
cout << endl;
inorder_traversal(root);
for (int i = 0; i < n; i++) {
cout << inorder[i];
if (i != n - 1)cout << " ";
}
return 0;
}