zoukankan      html  css  js  c++  java
  • 蓝桥杯练习系统历届试题 横向打印二叉树

    问题描述

    二叉树可以用于排序。其原理很简单:对于一个排序二叉树添加新节点时,先与根节点比较,若小则交给左子树继续处理,否则交给右子树。

    当遇到空子树时,则把该节点放入那个位置。

    比如,10 8 5 7 12 4 的输入顺序,应该建成二叉树如下图所示,其中.表示空白。

    ...|-12
    10-|
    ...|-8-|
    .......|...|-7
    .......|-5-|
    ...........|-4

    本题目要求:根据已知的数字,建立排序二叉树,并在标准输出中横向打印该二叉树。

    输入格式

    输入数据为一行空格分开的N个整数。 N<100,每个数字不超过10000。

    输入数据中没有重复的数字。

    输出格式

    输出该排序二叉树的横向表示。为了便于评卷程序比对空格的数目,请把空格用句点代替:

    样例输入1
    10 5 20
    样例输出1
    ...|-20
    10-|
    ...|-5
    样例输入2
    5 10 20 8 4 7
    样例输出2
    .......|-20
    ..|-10-|
    ..|....|-8-|
    ..|........|-7
    5-|
    ..|-4
     
    思路:

    首先就是题意,把图片顺时针旋转90°..
    然后,建立排序二叉树没有问题,
    输出...
    1.中序遍历递归出每个节点所在行的字符串保存起来,过程中记录当前节点在str中的层数tier和当前节点需要扩展的|位置.
    2.递归每个节点到它的左右子树所在层+|.

    非常好的关于二叉树的题目.......还真是喜欢这个递归呢.........T_T

    附代码:

    /*
    蓝桥杯横向打印二叉树
    首先就是题意,把图片顺时针旋转90°..
    然后,建立排序二叉树没有问题,
    输出...
    1.中序遍历递归出每个节点所在行的字符串保存起来,过程中记录当前节点在str中的层数tier和当前节点需要扩展的|位置.
    2.递归每个节点到它的左右子树所在层+|.
    */
    
    #include <stdio.h>
    #include <algorithm>
    #include <iostream>
    using namespace std;
    
    char str[210][30000];
    int cnt = 0;
    int cntStr = 0;
    
    struct Node {
        int val; // 当前节点的值
        int lson, rson; // 左右孩子节点的编号
        int  num; // 当前节点在数组中的编号
        int tier; // 表示当前节点在str中是第tier个
        int ls; // 当前节点应该扩展的|位置
    
        Node() {
            num = -1;
            lson = -1;
            rson = -1;
            tier = -1;
            ls = -1;
        }
    }tree[210];
    
    void add(int rt, int val, int num) { // 参数:根节点 加入的值 加入值的序号
        if (tree[rt].val < val) { // 交给右子树
            if (tree[rt].rson == -1) {
                tree[rt].rson = num;
                tree[num].val = val;
                tree[num].num = num;
            }
            else add(tree[rt].rson, val, num);
        }
        else {
            if (tree[rt].lson == -1) {
                tree[rt].lson = num;
                tree[num].val = val;
                tree[num].num = num;
            }
            else add(tree[rt].lson, val, num);
        }
    }
    
    void midSearch(int rt) { // 中序遍历
        if (tree[rt].rson != -1) {
            midSearch(tree[rt].rson);
        }
        printf("%d
    ", tree[rt].val);
        if (tree[rt].lson != -1)
        midSearch(tree[rt].lson);
    }
    
    int getlen(int num) {
        int cnt = 0;
        while(num) {
            num /= 10;
            cnt++;
        }
        return cnt;
    }
    
    void printToStr(int rt, int len) { // 每个节点所在的字符串输出到字符串str里 len表示遍历到当前数字的时候 前面已经确定的长度
        if (tree[rt].rson != -1) {
            printToStr(tree[rt].rson, len + getlen(tree[rt].val) - 1 +  (rt == 0 ? 2 : 4));
        }
        for (int i=0; i<len; ++i)
            str[cntStr][i] = '.';
        sprintf(str[cntStr]+len, "%s%d%s", rt == 0 ? "" : "|-", tree[rt].val, ((tree[rt].lson == -1 && tree[rt].rson == -1) ? "
    " : "-|
    "));
        tree[rt].tier = cntStr;
        if (tree[rt].lson != -1 || tree[rt].rson != -1)
        tree[rt].ls = len + (rt == 0 ? 0 : 2) + getlen(tree[rt].val) + 1;
        //cout << tree[rt].ls << "*
    ";
        cntStr++;
        if (tree[rt].lson != -1) {
            printToStr(tree[rt].lson, len + getlen(tree[rt].val) - 1 + (rt == 0 ? 2 : 4));
        }
    }
    
    void format(int rt) { // 将字符串里的|加上 len表示当前节点的|位置
        if (tree[rt].rson != -1) {
            format(tree[rt].rson);
            for (int i=tree[tree[rt].rson].tier; i<=tree[rt].tier; ++i) {
                str[i][tree[rt].ls] = '|';
            }
        }
        if (tree[rt].lson != -1) {
            format(tree[rt].lson);
            for (int i=tree[rt].tier; i<=tree[tree[rt].lson].tier; ++i) {
                str[i][tree[rt].ls] = '|';
            }
        }
    }
    
    int main() {
    //    freopen("1.in.cpp", "r", stdin);
        int n;
        scanf("%d", &n);
        tree[0].val = n; // 根节点为0
        tree[0].num = 0;
    
        while(~scanf("%d", &n)) {
            add(0, n, ++cnt); // 在二叉树上加入n
        }
    
        printToStr(0, 0); // 每个节点对应的字符串加入到str中
        format(0);
    
        for (int i=0; i<cntStr; ++i) {
            printf("%s", str[i]);
        }
        return 0;
    }
    

      

  • 相关阅读:
    4.定时器
    LSTM分类层的理解
    对机器学习中end-to-end learning(端到端学习)的理解
    对非极大值限制(NMS)的理解
    ROI pooling
    softmax的理解
    长尾理论(long tail )的理解
    对双线性插值的理解
    RPN的理解
    卷积神经网络(CNN)和Faster-RCNN的理解
  • 原文地址:https://www.cnblogs.com/icode-girl/p/5513110.html
Copyright © 2011-2022 走看看