原题目: 1102 Invert a Binary Tree (25 分)
题意
给出一棵二叉树的结点个数N(编号0-N-1),接着N行给出相应结点的左孩子和右孩子;
👉分别以层序遍历和中序遍历输出这棵二叉树反转后的二叉树。
分析
- 反转二叉树就是存储的时候所有左右结点都交换。
&1 法一: 由于题目给出的是每个结点的孩子表,因此,可以在”输入“过程中就直接交换左右结点。
&2 法二: ①在DFS时按 “右左根” 的顺序递归;②在获得层序序列的排序中(结点元素多一个成员layer记录层次,在DFS过程中可以生成),设置cmp函数为——先按层序递增排序,同层时再按index递减排序。 - ⭐用DFS方法进行中序遍历,获得中序序列——从根结点开始DFS,因此 关键是找到根结点——需要一个数组have记录下标对应结点是否为孩子结点,方便找根结点。
- 为了得到层序序列,在每个结点元素中加入成员index记录按完全二叉树规则存储的下标(index递增排序即得到层序序列)——这可以在DFS过程中生成(此处参考 👉传送门:中序后序转层序(无须建树))。
知识点
- 反转二叉树——存储时所有左右结点都交换。
- 在DFS过程中生成结点的完全二叉树下标index和层次layer。
- ⭐无须建树得到层序遍历序列——设置index和layer变量,利用sort+cmp函数。
- 将字符串转成对应的数值型变量—— stoi()(转int型)、stod(转double型)等。
词汇
WORDS | 释义 | WORDS | 释义 |
---|---|---|---|
indice | 指标 | adjacent | 相邻的,毗邻的 |
CODE
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct node{
int id; //题给id
int lchild, rchild; //孩子结点下标
int index; //按完全二叉树规则存储的下标
int layer; //层次
};
vector<node> in, v(11);
bool cmp(node a, node b){
return a.index<b.index;
}
void DFS(int root, int index, int layer);
int main()
{
int n, have[11] = {0}; //数组have记录结点是否出现在孩子结点中(用于找根结点)
cin >> n;
for ( int i=0; i<n; i++ ){
v[i].id = i;
string l, r;
cin >> l >> r;
//左右结点反过来存储
if ( l!="-" ){
v[i].rchild = stoi(l);
have[stoi(l)] = 1; //id为stoi(r)的结点是孩子结点
}
else
v[i].rchild = -1;
if ( r!="-" ){
v[i].lchild = stoi(r);
have[stoi(r)] = 1;
}
else
v[i].lchild = -1;
}
//找根结点
int root = -1; //根结点下标
while( have[root] ) root++;
//得中序遍历
DFS(root, 0, 1);
//根据index递增排序即得到层序序列
vector<node> level(in); //先复制一份,用于层序
sort(level.begin(), level.end(), cmp);
for ( int i=0; i<n; i++ ){
printf("%d%s", level[i].id, i==n-1?"":" ");
}
cout << endl;
//输出中序
for ( int i=0; i<n; i++ )
printf("%d%s", in[i].id, i==n-1?"":" ");
return 0;
}
void DFS(int root, int index, int layer){
if ( v[root].lchild!=-1 ) DFS(v[root].lchild, 2*index+1, layer+1);
in.push_back({root, 0, 0, index, layer}); //左右孩子不重要
if ( v[root].rchild!=-1 ) DFS(v[root].rchild, 2*index+2, layer+1);
}
法二的cmp函数
bool cmp(node a, node b){
if ( a.level!=b.level ) return a.level<b.level;
return a.index<b.index;
}