#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from collections import namedtuple
from io import StringIO
import math
#定义节点格式
Node = namedtuple('Node', ['data', 'left', 'right'])
#数组转换为树
def treetran(a):
trantree = Node(a[3],
Node(a[1],
Node(a[0],None, None),
Node(a[2], None, None)),
Node(a[5],
Node(a[4],None, None),
Node(a[6], None, None)))
if a[3]==None:
trantree=Node(None,None,None)
else:
if a[1]==None:
trantree=Node(a[0],
None,
Node(a[5],
Node(a[4],None,None),
Node(a[6],None,None)))
if a[5]==None:
trantree=Node(a[0],None,None)
else:
if a[5]==None:
trantree=Node(a[0],
Node(a[1],
Node(a[0],None,None),
Node(a[2],None,None)),
None)
return trantree
#为了便于储存节点下的数据,用于计算树的高度
class Queue(object):
def __init__(self):
self.queue = []
def enqueue(self, b):
self.queue.insert(0, b)
def dequeue(self):
return self.queue.pop()
def isEmpty(self):
return self.queue == []
#计算高度
def getheight(node):
if not node:
return 0
else:
return max(getheight(node.left), getheight(node.right)) + 1
#填充空格
def add_padding(str, pad_length_value):
str = str.strip()
return str.center(pad_length_value, ' ')
#列出节点、空格、斜杠,打印
def pretty_print(tree):
output = StringIO()
pretty_output = StringIO()
current_level = Queue()
next_level = Queue()
current_level.enqueue(tree)
depth = 0
#获取树深度
#获取节点数据并储存
if tree:
while not current_level.isEmpty():
current_node = current_level.dequeue()
output.write('%s ' % current_node.data if current_node else 'N ')
#若节点不是空的,返回节点的数值,如果是空的,返回N,如图,显示为N
next_level.enqueue(
current_node.left if current_node else current_node)
next_level.enqueue(
current_node.right if current_node else current_node)
if current_level.isEmpty():
if sum([i is not None for i in next_level.queue]
): #有节点,不全为空
current_level, next_level = next_level, current_level
depth = depth + 1
output.write('\n')
print('the tree print level by level is :')
print(output.getvalue())
print("current tree's depth is %i" % (depth+1))
#节点位置确定
output.seek(0)
pad_length = 3#pad_length表示每个节点在图中所占的格数,如图,占3格
keys = []
spaces = int(math.pow(2, depth))
while spaces > 0:
skip_start = spaces * pad_length
skip_mid = (2 * spaces - 1) * pad_length
key_start_spacing = ' ' * skip_start
key_mid_spacing = ' ' * skip_mid
keys = output.readline().split(' ') #读取一行
padded_keys = (add_padding(key, pad_length) for key in keys)
padded_str = key_mid_spacing.join(padded_keys)
complete_str = ''.join([key_start_spacing, padded_str])
pretty_output.write(complete_str)
#插入空格和斜线
slashes_depth = spaces
print('current slashes depth im_resize:')
print(spaces)
print("current levle's list is:")
print(keys)
spaces = spaces // 2
if spaces > 0:
pretty_output.write('\n') # 用'\n'转行
cnt = 0
while cnt < slashes_depth:
inter_symbol_spacing = ' ' * (pad_length + 2 * cnt)
symbol = ''.join(['/', inter_symbol_spacing, '\\'])
symbol_start_spacing = ' ' * (skip_start-cnt-1)
symbol_mid_spacing = ' ' * (skip_mid-2*(cnt+1))
pretty_output.write(''.join([symbol_start_spacing, symbol]))
for i in keys[1:-1]:
pretty_output.write(''.join([symbol_mid_spacing, symbol]))
pretty_output.write('\n')
cnt = cnt + 1
print(pretty_output.getvalue())
#原始树
a=[None,None,None,None,None,None,None]
tree1=treetran(a)
#添加指定位置的节点
def inputn(a,addns):
xn=0
for x in a:
if x is not None:
xn=xn+1
addns.append(x)
addns.sort()
while len(addns)<7:addns.append(None)
return addns
#删除指定节点
def deln(a,deln):
dela=a.index(deln)
a.remove(deln)
a.insert(dela,None)
return a
#搜索
def searchn(ta,sear):
searnum=ta.index(sear)
if searnum==3:
print("搜索元素:%d,no parent"%sear)
if (searnum==1)or(searnum==5):
print("搜索元素:%d,parent=%d"%(sear,ta[3]))
if (searnum==0)or(searnum==2):
print("搜索元素:%d,parent=%d"%(sear,ta[1]))
if (searnum==4)or(searnum==6):
print("搜索元素:%d,parent=%d"%(sear,ta[5]))
#打印二叉树
def drawtree(tree):
if __name__ == '__main__':
pretty_print(tree)
控制命令:
#新建
>>> a1=inputn(a,[2,6,3,10,26,7])
>>> tree1=treetran(a1)
>>> drawtree(tree1)
#删除
>>> a2=deln(a1,3)
>>> tree2=treetran(a2)
>>> drawtree(tree2)
#添加
>>> a3=inputn(a2,[8])
>>> tree3=treetran(a3)
>>> drawtree(tree3)
#搜索
>>> searchn(a3,10)
结果:
>>> #新建
>>> a1=inputn(a,[2,6,3,10,26,7])
>>> tree1=treetran(a1)
>>> drawtree(tree1)
the tree print level by level is :
7
3 26
2 6 10 None
current tree's depth is 3
current slashes depth im_resize:
4
current levle's list is:
['7', '\n']
current slashes depth im_resize:
2
current levle's list is:
['3', '26', '\n']
current slashes depth im_resize:
1
current levle's list is:
['2', '6', '10', 'None', '\n']
7
/ \
/ \
/ \
/ \
3 26
/ \ / \
/ \ / \
2 6 10 None
>>> #删除
>>> a2=deln(a1,3)
>>> tree2=treetran(a2)
>>> drawtree(tree2)
the tree print level by level is :
2
N 26
N N 10 None
current tree's depth is 3
current slashes depth im_resize:
4
current levle's list is:
['2', '\n']
current slashes depth im_resize:
2
current levle's list is:
['N', '26', '\n']
current slashes depth im_resize:
1
current levle's list is:
['N', 'N', '10', 'None', '\n']
2
/ \
/ \
/ \
/ \
N 26
/ \ / \
/ \ / \
N N 10 None
>>> #添加
>>> a3=inputn(a2,[8])
>>> tree3=treetran(a3)
>>> drawtree(tree3)
the tree print level by level is :
8
6 26
2 7 10 None
current tree's depth is 3
current slashes depth im_resize:
4
current levle's list is:
['8', '\n']
current slashes depth im_resize:
2
current levle's list is:
['6', '26', '\n']
current slashes depth im_resize:
1
current levle's list is:
['2', '7', '10', 'None', '\n']
8
/ \
/ \
/ \
/ \
6 26
/ \ / \
/ \ / \
2 7 10 None
>>> #搜索
>>> searchn(a3,10)
搜索元素:10,parent=26