蓝桥杯笔记

第四周是贪心算法的练习

横向打印二叉树(C++)

Description

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

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

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

...|-12

10-|

...|-8-|

.......|...|-7

.......|-5-|

...........|-4

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

Input

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

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

Output

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

Sample Input 1

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

Sample Output 1

10 5 20
代码:
#include<iostream>
#include<sstream>

const int maxn = 200;

struct node{
    int left,right; 
    int left_s,right_s; //左右子树节点数 
    int v,id,ak;
    char a[10];//用于存放v的字符串形式 
}Nodes[maxn];

char map[maxn][maxn]; 
using namespace std;

void BinaryTree_set(int rt,int k){ 
    if(Nodes[k].v > Nodes[rt].v){ 
        Nodes[rt].right_s++; 
        if(Nodes[rt].right != -1){ 
            BinaryTree_set(Nodes[rt].right,k); //递归以右子树的根节点为根节点插入k节点 
        }else{ //右子树不存在 
            Nodes[rt].right = k;//直接将当前根节点的右子树为k 
        }
    }else{//同理 
        Nodes[rt].left_s++;
        if(Nodes[rt].left != -1){
            BinaryTree_set(Nodes[rt].left,k); 
        }else{
            Nodes[rt].left = k;
        }
    }
}

void Set_id(int rid,int k){ 
    Nodes[k].id = rid + Nodes[k].right_s + 1; 
    if(Nodes[k].right != -1){
        Set_id(rid,Nodes[k].right);
    if(Nodes[k].left != -1){
        Set_id(Nodes[k].id,Nodes[k].left);
    }
}

void Map_set(int k,int index){ 
    for(int i = 0;i < Nodes[k].ak;i++){ 
        map[Nodes[k].id][index + i] = Nodes[k].a[Nodes[k].ak - i - 1];
    }
    index += Nodes[k].ak; 
    if(Nodes[k].right != -1 || Nodes[k].left != -1){ 
        map[Nodes[k].id][index++] = '-'; 
        
        int max = Nodes[k].id;
        int min = Nodes[k].id; 
        
        if(Nodes[k].right != -1){
            min = Nodes[Nodes[k].right].id; 
            map[Nodes[Nodes[k].right].id][index + 1] = '-';
            Map_set(Nodes[k].right,index + 2); 
        }
        if(Nodes[k].left != -1){
            max = Nodes[Nodes[k].left].id;
            map[Nodes[Nodes[k].left].id][index + 1] = '-';
            Map_set(Nodes[k].left,index + 2); 
        }
        
        for(int i = min; i <= max;i++){
            map[i][index] = '|';
        }
        
        map[Nodes[k].id][index + 1] = '\0'; 
    }else{
        map[Nodes[k].id][index] = '\0';
        return;
    }
} 
 
int main(){
    string s;
    getline(cin,s);
    istringstream ss(s);
    int e;
    int n = 0;
    int A[maxn];
    while(ss >> e){ //读取输入值 
        A[n++] = e;
    }
    
    for(int i = 0;i < n;i++){
        int e = A[i];
        Nodes[i].right = Nodes[i].left = -1;
        Nodes[i].right_s = Nodes[i].left_s = 0;
        Nodes[i].v = e;
        Nodes[i].ak = 0;
        while(e){
            Nodes[i].a[Nodes[i].ak++] = e % 10 + '0';
            e = e / 10;
        }
    }
    for(int i = 1;i < n;i++){
        BinaryTree_set(0,i);
    }
    Set_id(0,0);
    for(int i = 1;i < maxn;i++){
        for(int j = 0;j < maxn;j++){
            map[i][j] = '.';    
        }
    }
    Map_set(0,0);
    for(int i = 1;i <=n;i++){
        cout<<map[i]<<endl; 
    } 
    return 0;
} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值