1102 Invert a Binary Tree (25 分)

跟着柳婼学姐学习的笔记ヾ(≧▽≦*)o

原题目: 1102 Invert a Binary Tree (25 分)

题意

给出一棵二叉树的结点个数N(编号0-N-1),接着N行给出相应结点的左孩子和右孩子;
👉分别以层序遍历和中序遍历输出这棵二叉树反转后的二叉树。

分析

  1. 反转二叉树就是存储的时候所有左右结点都交换
    &1 法一: 由于题目给出的是每个结点的孩子表,因此,可以在”输入“过程中就直接交换左右结点。
    &2 法二: ①在DFS时按 “右左根” 的顺序递归;②在获得层序序列的排序中(结点元素多一个成员layer记录层次,在DFS过程中可以生成),设置cmp函数为——先按层序递增排序,同层时再按index递减排序。
  2. ⭐用DFS方法进行中序遍历,获得中序序列——从根结点开始DFS,因此 关键是找到根结点——需要一个数组have记录下标对应结点是否为孩子结点,方便找根结点。
  3. 为了得到层序序列,在每个结点元素中加入成员index记录按完全二叉树规则存储的下标(index递增排序即得到层序序列)——这可以在DFS过程中生成(此处参考 👉传送门:中序后序转层序(无须建树))。

知识点

  1. 反转二叉树——存储时所有左右结点都交换。
  2. 在DFS过程中生成结点的完全二叉树下标index和层次layer。
  3. ⭐无须建树得到层序遍历序列——设置index和layer变量,利用sort+cmp函数。
  4. 将字符串转成对应的数值型变量—— 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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值