横向打印二叉树

题目是:

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

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

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

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

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

真的毒瘤,其实题目不难,就是一个普通dfs,但是输出好麻烦,我下午一个小时的时间dbug,最后发现原来左右子树的数量写反了,哎难受,思路就是先建立一颗二叉树,然后递归输出,用一个vector来保存答案。我们首先应该找到每个结点的位置,行坐标和纵坐标,记录每个结点的父亲结点,然后再找规律,通过找规律发现他们的父亲结点的前缀是当前结点的父亲节点前面的部分,我们在递归到当前结点的时候只需要把父亲结点的类型判断一下,统计一下父节点的字符长度,并加点数,然后记录本层结点的横纵坐标,递归下去就可以了。

做过的最恶心的dfs题之一,还有个是洗牌的那个final题,最近dfs都要dbug好久,越来越菜!!

code:

#include <iostream>
#include <string>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int N = 110;
int nums[N];
int s2i(string s){
    int res=0;
    for(int i=0;i<s.size();i++){
        res*=10;
        res+=(s[i]-'0');
    }
    return res;
}

string i2s(int a){
    string s="";
    while(a){
        s+=(a%10+'0');
        a/=10;
    }
    reverse(s.begin(),s.end());
    return s;
}

struct node{
    int val;
    node* left;
    node* right;
    int lnums;
    int rnums;
    int h;
    bool isroot;
    bool isend;
    int colpos;
    int rowpos;
    node* fa;
    node(int v){this->val=v;this->left=NULL;this->right=NULL;this->fa=NULL;this->isroot=false;this->lnums=0;this->rnums=0;
                this->isend=false;}
};

void insert(node*& rt,node* fa,int val,int h){
    if(rt==NULL){
        rt=(node*)new node(val);
        rt->h=h+1;
        rt->fa=fa;
        rt->isend=true;
        return ;
    }
    if(val>rt->val){
        rt->rnums++;
        rt->isend=false;
        insert(rt->right,rt,val,rt->h);
    }
    else {
        rt->lnums++;
        rt->isend=false;
        insert(rt->left,rt,val,rt->h);
    }
}

vector<string> res;

void draw(node* rt){
    if(!rt)return ;
    string ret="";
    if(rt->isroot){
        ret+=i2s(rt->val);
        ret+="-|";
        res[rt->rnums]=ret;
        rt->colpos=0;
        rt->rowpos=rt->rnums;
    }
    else { 
        node* tem=rt;
        // cout<<tem->fa->colpos<<endl;
        if(tem->fa->isroot)ret+=res[tem->fa->rowpos].substr(0,tem->fa->colpos);
        else ret+=res[tem->fa->rowpos].substr(0,tem->fa->colpos-2);
        node* gfa=tem->fa->fa;
        if(gfa){
            if(gfa->left&&gfa->left->right==tem){
                ret+='|';
            }
            else if(gfa->right&&gfa->right->left==tem){
                ret+='|';
            }
            else{
                ret+='.';
            }
        }
        string faval=i2s(tem->fa->val);
        int dotdta=faval.size();
        if(rt->fa->isroot){
            dotdta+=1;
        }
        else{
            dotdta+=2;
        }
        for(int i=0;i<dotdta;i++){
            ret+='.';
        }
        ret+="|-";
        rt->colpos=ret.size();
        ret+=i2s(rt->val);
        if(rt->isend){
            
        }
        else ret+="-|";
        if(tem->fa->left&&tem->fa->left==rt){
            res[tem->fa->rowpos+rt->rnums+1]=ret;
            rt->rowpos=tem->fa->rowpos+rt->rnums+1;
        }
        else {
            res[tem->fa->rowpos-rt->lnums-1]=ret;
            rt->rowpos=tem->fa->rowpos-rt->lnums-1;
        }
    }
    draw(rt->left);
    draw(rt->right);
}
int main(){
    string s;
    int idx=0;
    node* rt=NULL;
    while(cin>>s){
        int t = s2i(s);
        insert(rt,NULL,t,-1);
    }
    rt->isroot=true;
    res.resize(rt->lnums+rt->rnums+1);
    draw(rt);
    for(int i=0;i<res.size();i++)cout<<res[i]<<endl;
}

 

posted @ 2020-07-23 16:20  kstranger  阅读(401)  评论(0)    收藏  举报