好久没写博客了...因为好久没刷题了QAQ...
还是先附上大佬博客Orz:
https://blog.csdn.net/survivorone/article/details/60871378
https://blog.csdn.net/qq_40103462/article/details/79527537
这道题还是蛮好的,但是我太菜了啊55555...大体思路就是,后序遍历,先记录从根到当前结点的完整字符串,再判断输出时是"."还是"|",最后输出本节点的数,如果是非叶子节点,再加上"-|"。
需要注意的是,改变node时需要加引用,因为它本身就是Node *类型;dfs函数中string s,p不能加引用,因为其记录的是从根到当前节点的路径而不是整个遍历过程的路径。如果感觉有点乱,就去掉注释看看中间过程吧。
还有其他的细节就不多说了,直接附上100%通过代码:
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<vector>
#include<malloc.h>
using namespace std;
const int INF=0x3f3f3f3f;
const int MAX=10000*100+10;
typedef struct Node
{
int val;//值
char num[7];//数值对应的字符串
int hei;//深度
struct Node *lchild,*rchild;
//char ans[MAX];//记录每个节点的答案
}Node;
Node *node=NULL;
int root;//树根
void change(char t[],int num)//将数值转化为字符串
{
int j=0,k=num;
while(k)
{
t[j++]=(k%10+'0');
k/=10;
}
for(int i=0,ii=j-1;i<ii;i++,ii--)
swap(t[i],t[ii]);
t[j]='\0';
//cout<<t<<endl;
}
//构建二叉树
void ins(Node * &t,int num,int height)//要加引用!!!
{
if(t==NULL)//插入位置
{
t=(Node *)malloc(sizeof(Node));
t->val=num;
change(t->num,num);
t->hei=height+1;
//cout<<"t->val="<<t->val<<" t->hei="<<t->hei<<endl;
t->lchild=t->rchild=NULL;
}
else if(t->val>num)
ins(t->lchild,num,t->hei);
else
ins(t->rchild,num,t->hei);
}
//后序遍历
void Inorder_traversal(Node *t)
{
if(t==NULL)
return;
Inorder_traversal(t->rchild);
printf("num=%d,hei=%d\n",t->val,t->hei);
Inorder_traversal(t->lchild);
}
void dfs(Node * &t,string s,string p)//s保存完整字符串,p保存从树根到当前节点左右移动的关系
{
if(t->val==root)//根节点
s+=t->num;
else//其余节点
{
s+="-|-";
s+=t->num;
}
if(t->rchild)
{
dfs(t->rchild,s,p+"1");
}
int len=s.length();
//cout<<"val="<<t->val<<" s="<<s<<" len="<<len<<" p="<<p<<endl;
len-=(strlen(t->num)+2);
int cnt=1,lenp=p.length();
for(int i=0;i<len;i++)
{
if(s[i]<='9'&&s[i]>='0')
printf(".");
else if(s[i]=='-') //-|-
printf(".");
else if(s[i]=='|')
{
//cout<<endl<<"cnt="<<cnt<<" lenp="<<lenp<<" p[cnt]="<<p[cnt]<<endl;
if(cnt<lenp&&p[cnt]==p[cnt-1])//左右孩子关系
printf(".");
else
printf("|");
cnt++;//无论哪种情况都要++
}
}
if(t->val==root)
printf("%s",t->num);
else
printf("|-%s",t->num);
if(t->lchild||t->rchild)//非叶子节点
printf("-|");
printf("\n");
if(t->lchild)
{
dfs(t->lchild,s,p+"0");
}
}
int main()
{
int x;
/*for(int i=1;i<=6;i++)
{
scanf("%d",&x);
ins(node,x,-1);
}*/
while(scanf("%d",&x)==1)
{
ins(node,x,-1);
}
//Inorder_traversal(node);//后序遍历
root=node->val;
string s="";
string p="";
dfs(node,s,p);
return 0;
}
/*
5 10 20 8 4 7
5 4 3 6 7
5 3 7 6 4
10 8 5 7 12 4
1 3 5 7 9 2 4 6 8
5 4 20 10 6 8
*/