앞에 작성 :
트리 시각화 (코드 2)에는 일부 패키지가 필요합니다. 미리 설치하십시오 (파이썬 환경이 괜찮다면 코드 1은 필요하지 않습니다)
from collections import Iterable
import networkx as nx
import matplotlib.pyplot as plt
1. 이진 트리 만들기
class TreeNode:
'''二叉搜索树节点的定义'''
def __init__(self, val):
self.val = val
self.left = None
self.right = None
class OperationTree:
'''二叉搜索树操作'''
def insert(self, root, val):
'''二叉搜索树插入操作'''
if root == None:
root = TreeNode(val)
elif val < root.val:
root.left = self.insert(root.left, val)
elif val > root.val:
root.right = self.insert(root.right, val)
return root
def query(self, root, val):
'''二叉搜索树查询操作'''
if root == None:
return False
if root.val == val:
return True
elif val < root.val:
return self.query(root.left, val)
elif val > root.val:
return self.query(root.right, val)
def findMin(self, root):
'''查找二叉搜索树中最小值点'''
if root.left:
return self.findMin(root.left)
else:
return root
def findMax(self, root):
'''查找二叉搜索树中最大值点'''
if root.right:
return self.findMax(root.right)
else:
return root
def delNode(self, root, val):
'''删除二叉搜索树中值为val的点'''
if root == None:
return
if val < root.val:
root.left = self.delNode(root.left, val)
elif val > root.val:
root.right = self.delNode(root.right, val)
# 当val == root.val时,分为三种情况:只有左子树或者只有右子树、有左右子树、即无左子树又无右子树
else:
if root.left and root.right:
# 既有左子树又有右子树,则需找到右子树中最小值节点
temp = self.findMin(root.right)
root.val = temp.val
# 再把右子树中最小值节点删除
root.right = self.delNode(root.right, temp.val)
elif root.right == None and root.left == None:
# 左右子树都为空
root = None
elif root.right == None:
# 只有左子树
root = root.left
elif root.left == None:
# 只有右子树
root = root.right
return root
def printTree(self, root):
# 打印二叉搜索树(中序打印,有序数列)
if root == None:
return
self.printTree(root.left)
print(root.val, end = ' ')
self.printTree(root.right)
if __name__ == '__main__':
List = [17,5,35,2,11,29,38,9,16,8]
root = None
op = OperationTree()
for val in List:
root = op.insert(root,val)
print('中序打印二叉搜索树:', end = ' ')
op.printTree(root)
print('')
print('根节点的值为:', root.val)
print('树中最大值为:', op.findMax(root).val)
print('树中最小值为:', op.findMin(root).val)
print('查询树中值为5的节点:', op.query(root, 5))
print('查询树中值为100的节点:', op.query(root, 100))
print('删除树中值为16的节点:', end = ' ')
root = op.delNode(root, 16)
op.printTree(root)
print('')
print('删除树中值为5的节点:', end = ' ')
root = op.delNode(root, 5)
op.printTree(root)
print('')
2. 트리 구조의 시각화
class Node:
def __init__(self, value, left=None, right=None):
self.value = value # 节点的值
self.left = left # 左子节点
self.right = right # 右子节点
from collections import Iterable
class BinaryTree:
def __init__(self, seq=()):
assert isinstance(seq, Iterable) # 确保输入的参数为可迭代对象
self.root = None
self.insert(*seq)
def insert(self, *args):
if not args:
return
if not self.root:
self.root = Node(args[0])
args = args[1:]
for i in args:
seed = self.root
while True:
if i > seed.value:
if not seed.right:
node = Node(i)
seed.right = node
break
else:
seed = seed.right
else:
if not seed.left:
node = Node(i)
seed.left = node
break
else:
seed = seed.left
def minNode(self):
node = self.root
while node.left:
node = node.left
return node
def maxNode(self):
node = self.root
while node.right:
node = node.right
return node
import networkx as nx
import matplotlib.pyplot as plt
def create_graph(G, node, pos={
}, x=0, y=0, layer=1):
pos[node.value] = (x, y)
if node.left:
G.add_edge(node.value, node.left.value)
l_x, l_y = x - 1 / 2 ** layer, y - 1
l_layer = layer + 1
create_graph(G, node.left, x=l_x, y=l_y, pos=pos, layer=l_layer)
if node.right:
G.add_edge(node.value, node.right.value)
r_x, r_y = x + 1 / 2 ** layer, y - 1
r_layer = layer + 1
create_graph(G, node.right, x=r_x, y=r_y, pos=pos, layer=r_layer)
return (G, pos)
def draw(node): # 以某个节点为根画图
graph = nx.DiGraph()
graph, pos = create_graph(graph, node)
fig, ax = plt.subplots(figsize=(8, 10)) # 比例可以根据树的深度适当调节
nx.draw_networkx(graph, pos, ax=ax, node_size=300)
plt.show()
if __name__ == '__main__':
List = [17,5,35,2,11,29,38,9,16,8]
tree = BinaryTree()
tree.insert(*List)
draw(tree.root)