概要:
给一个二叉树,代码实现输出俯视图,如:
代码实现:
#coding=utf8
#构造树节点
'''
基本思想:
对于每个节点输出关于根节点的层级和左右距离
树从0层开始计数
左距离:左子树上节点对于跟节点为1
右距离:右字数上节点对于跟节点为-1
相当于以树的根节点为坐标原点,每个树中的节点对应一个坐标轴
横轴表示距离,纵轴表示树的深度
树的俯视图即输出:这些点映射到横轴上,如有重叠取第一个,组成的序列。
待优化的地方:
1)在得到坐标后可以在O(n)的时间取得结果,我这里稍微复杂了点。
'''
class node(object):
def __init__(self, data=None, left=None, right=None,x=0,y=0):
self.data = data
self.left = left
self.right = right
self.x=x
self.y=y
def pre_order(tree):
if tree==None:
return
print (tree.data)
pre_order(tree.left)
pre_order(tree.right)
#计算每个点的坐标,横坐标表示距离,纵坐标表示层级
def points(tree):
if tree == None:
return
q = []
q.append(tree)
rs=[] #格式如["D",0,0]
level=0;#表示层级
current_level_num=1;#表示当前层的节点个数
next_level_num=0;#表示下一层节点个数
d=[]#用于存储当前层级的节点
while q:
current = q.pop(0)
d.append(current)
current_level_num=current_level_num-1
if current.left != None:
q.append(current.left)
next_level_num = next_level_num + 1
current.left.x=current.x+1 #如果是往左,则在父亲节点基础上加1
if current.right !=None:
q.append(current.right)
next_level_num = next_level_num + 1
current.right.x=current.x-1#如果是往右,则在父亲节点上减 1
if current_level_num==0:#当前层没有节点的时候层级加1
current_level_num=next_level_num
next_level_num=0
for tmp in d: #同一层级节点赋值
tmp.y=level
rs.append([tmp.data,tmp.x,tmp.y])
d=[]
level = level + 1
return rs;
def get_tree_border(node_points):
rs=[]
lenth=len(node_points)
x_set=set()
for item in node_points:
x_set.add(item[1])
x_set=list(x_set)
x_set.sort(reverse=True)
for item_set in x_set:
tmp_rs=[]
for item_node in node_points:
if(item_set==item_node[1]):
tmp_rs.append(item_node)
tmp_rs.sort(key=lambda obj:obj[2])
rs.append(tmp_rs[0][0])
return rs
if __name__ == '__main__':
tree = node('a',node('b',
node("d"),
node("e",
node("h",
node("l",
node("p"))
,node("m")),
node("z")))
,node('c',
node("f",
node("j"),
node("k",
right=node("n",
right=node("o"))))
,node("g")
)
)
print("前序遍历一把")
pre_order(tree)
print("树的俯视结果如下:")
node_points=points(tree)
rs=get_tree_border(node_points)
print(rs)
最后得到结果:
['p', 'd', 'b', 'a', 'c', 'g', 'o']