平衡二叉树(功能:添加、删除、搜索)

#!/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

    原文作者:平衡二叉树
    原文地址: https://blog.csdn.net/opiticer/article/details/78541631
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞