A1102 Invert a Binary Tree (25 分| 树的遍历,附详细注释,逻辑分析)

写在前面

  • 思路分析
    • 反转1棵2叉树,给出原2叉树的每个结点的左右孩子,输出它的层序和前序遍历
      • 镜像二叉树的层序遍历和中序遍历
    • 具体实现
      • 反转2叉树就是存储的时候所有左右结点都交换
      • 2叉树使用{id, l, r, index, level}存储每个结点的id, 左右结点,下标值,和当前层数
      • 根结点是所有左右结点中没有出现的那个结点
      • 已知根结点,用递归的方法可以把中序遍历的结果push_back到数组v1⾥面,直接输出是中序,排序输出是层序
        • 排序方式,层数小的排前面,相同层数时, index大的排前面
  • 知识盲点,学习ing
    • 待深入学习研究

测试用例

  • input:
    8
    1 -
    - -
    0 -
    2 7
    - -
    - -
    5 -
    4 6
    
    output:
    3 7 2 6 4 0 5 1
    6 5 7 4 3 2 0 1
    

ac代码

  • #include <vector>
    #include <iostream>
    #include <algorithm>
    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;
    }
    
  • 学习代码
    • 方法和一般的遍历一样, 只是先遍历右子树再遍历左子树
      • 容易理解
    #include<iostream>
    #include<vector>
    #include<queue>
    using namespace std;
    vector<vector<int> > v(10);
    vector<int> in, exist(10, 1), level;
    
    void inOrder(int root)
    {
        if(root==-1) return;//先遍历右子树再遍历左子树
        if(v[root][1]!=-1) inOrder(v[root][1]);
        in.push_back(root);
        if(v[root][0]!=-1) inOrder(v[root][0]);
    }
    
    int main()
    {
        int n, i, root, left, right;
        char l, r;
        scanf("%d", &n);
        for(i=0; i<n; i++)
        {
            cin>>l>>r;
            left = l=='-' ? -1 : l-'0';
            right = r=='-' ? -1 : r-'0';
            if(left>=0)
                exist[left]=0;
            if(right>=0)
                exist[right]=0;
            v[i].push_back(left);
            v[i].push_back(right);
        }
        for(i=0; i<n; i++) if(exist[i]) root=i;
        queue<int> q;
        q.push(root);
        while(q.size())
        {
            int tmp=q.front();
            q.pop();
            level.push_back(tmp);
            if(v[tmp][1]!=-1) q.push(v[tmp][1]);
            if(v[tmp][0]!=-1) q.push(v[tmp][0]);
        }
        inOrder(root);
        printf("%d", level[0]);
        for(i=1; i<n; i++) printf(" %d", level[i]);
        printf("\n%d", in[0]);
        for(i=1; i<n; i++) printf(" %d", in[i]);
        return 0;
    }
    
发布了328 篇原创文章 · 获赞 107 · 访问量 39万+

猜你喜欢

转载自blog.csdn.net/qq_24452475/article/details/100605417