[蓝桥杯]横向打印二叉树 Python满分解法

[蓝桥杯]横向打印二叉树 Python满分解法

#树的结点类定义
class Node:
    def __init__(self,left=0,right=0,w=0,line=0,leng=0):
        self.left=left
        self.right=right
        self.w=w
        self.line=line
        self.leng=leng


class Solution:
    def printTree(self,nums):
        #节点的处理,表示将第i个结点与树中本来存在的第cur个节点进行比较,从而不断的初始化构造树
        def push(i,cur):
            if node[i].w<node[cur].w:
                if node[cur].left :
                    push(i,node[cur].left)
                else:
                    node[cur].left=i
            else:
                if node[cur].right :
                    push(i,node[cur].right)
                else:
                    node[cur].right=i

        #计算编号为cnt的节点的字符串长度为多少
        def writele(cnt):
            if node[cnt].w<10:
                node[cnt].leng=1
            elif node[cnt].w<100:
                node[cnt].leng=2
            elif node[cnt].w<1000:
                node[cnt].leng=3
            elif node[cnt].w<10000:
                node[cnt].leng=4
            else:
                node[cnt].leng=5

        #通过原来的树,来计算某一个节点应该在后来打印的结果的第几行,从0开始计数
        #pos表示第几个节点
        def dsfline(pos):
            nonlocal lc
            if node[pos].right:
                dsfline(node[pos].right)
            node[pos].line=lc
            lc+=1
            if node[pos].left:
                dsfline(node[pos].left)
        #树的深度优先遍历,通过这个我们填充结果数组Map
        def dsf(cur,pos):
            t,p2=node[cur].w,node[cur].leng
            for i in range(pos+p2-1,pos-1,-1):
                Map[node[cur].line][i]=str(t%10)+'0'
                t//=10
            if node[cur].left or node[cur].right:
                Map[node[cur].line][pos+p2]='-'
                Map[node[cur].line][pos+p2+1]='|'
                if node[cur].right:
                    l2=node[node[cur].right].line
                    for i in range(node[cur].line-1,l2-1,-1):
                        Map[i][p2+pos+1]='|'

                    Map[l2][p2+pos+2]='-'
                    dsf(node[cur].right,pos+p2+3)

                if node[cur].left:
                    l2=node[node[cur].left].line
                    for i in range(node[cur].line,l2+1):
                        Map[i][p2+pos+1]='|'
                    Map[l2][p2+pos+2]='-'
                    dsf(node[cur].left,pos+p2+3)

        n=len(nums)
        #之所以设置为8n是因为我们一个字符最长为len(10000)=5,再加上另外4个字符为5+4=9
        #其中一定有n-1个重复,所以设置为9n-n-1,即8n个长度
        N=8*len(nums)
        lc=0
        Map=[['0']*N for _ in range(N)]
        new_node=Node(w=nums[0])
        node=list()
        node.append(new_node)
        writele(0)
        for i in range(1,n):
            node_add=Node(w=nums[i])
            node.append(node_add)
            push(i,0)
            writele(i)
        dsfline(0)
        dsf(0,0)
        for i in range(len(Map)):
            for j in range(len(Map[0])):
                if Map[i][j]=='0':
                    Map[i][j]='.'
        for i in range(len(nums)):
            flag=False
            for j in range(len(Map[0])):
                if Map[i][j]=='.':
                    if flag:
                        break
                    print('.',end='')
                elif Map[i][j]=='-' or Map[i][j]=='|':
                    print(Map[i][j],end='')
                else:
                    print(int(Map[i][j])//10,end='')
                    flag=True
            print('')

if __name__=='__main__':
    solution=Solution
    nums=[int(i) for i in input().split()]
    solution.printTree(solution,nums)


  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值