二叉树的实现
1.二叉树的节点类
由于二叉树由一组节点组成,首先定义一个表示二叉树节点的类。节点通过链接引用其子节点,没有子节点时python用None表示,也就是说空二叉树直接用None表示。
下面是用python定义的二叉树节点的类:
1 class BinTreeNode: 2 def __init__(self, data, left=None, right=None): 3 self.data = data 4 self.left = left 5 self.right = right
2.构建二叉树
通过节点信息构造二叉树第一次遍历我们构造 node 节点第二次遍历我们给 root 和 孩子赋值最后我们用 root 初始化这个类并返回一个对象
1 class BinTree(object):
2 def __init__(self, root=None):
3 self.root = root
4
5 @classmethod
6 def build_from(cls, node_list):
14 node_dict = {}
15 for node_data in node_list:
16 data = node_data['data']
17 node_dict[data] = BinTreeNode(data)
18 for node_data in node_list:
19 data = node_data['data']
20 node = node_dict[data]
21 if node_data['is_root']:
22 root = node
23 node.left = node_dict.get(node_data['left'])
24 node.right = node_dict.get(node_data['right'])
25 return cls(root)
26
27 """
28 二叉树的先序遍历:
29 先访问根节点,如果有左右孩子在递归调用自身
30 访问左右孩子节点
31 """
32 def preorder_trav(self, subtree):
33 if subtree:
34 print(subtree.data, end=',')
35 self.preorder_trav(subtree.left)
36 self.preorder_trav(subtree.right)
37 # 二叉树的层序遍历的一种实现
38 @staticmethod
39 def layer_trav(subtree):
40 cur_node = [subtree]
41 next_node = []
42 while cur_node or next_node:
43 for node in cur_node:
44 print(node.data, end=',')
45 if node.left:
46 next_node.append(node.left)
47 if node.right:
48 next_node.append(node.right)
49 cur_node = next_node
50 next_node = []
51
52 """
53 因为层序遍历是按顺序访问的
54 所以可以用队列来实现二叉树的层序遍历
55 """
56 @staticmethod
57 def layer_trav_use_queue(subtree):
58 q = Queue()
59 q.append(subtree)
60 while not q.is_empty():
61 node = q.pop()
62 print(node.data, end=',')
63 if node.left:
64 q.append(node.left)
65 if node.right:
66 q.append(node.right)
67
68 def reverse(self, subtree):
69 if subtree is not None:
70 subtree.left, subtree.right = subtree.right, subtree.left
71 self.reverse(subtree.left)
72 self.reverse(subtree.right)
3.用python内置的deque实现队列
1 from collections import deque 2 3 4 class Queue: 5 def __init__(self): 6 self._elem = deque() 7 8 def append(self, elem): 9 self._elem.append(elem) 10 11 def pop(self): 12 if self.is_empty(): 13 raise ValueError 14 return self._elem.popleft() 15 16 def is_empty(self): 17 return len(self._elem) == 0
4.二叉树实现的总代码:
from collections import deque
class Queue:
def __init__(self):
self._elem = deque()
def append(self, elem):
self._elem.append(elem)
def pop(self):
if self.is_empty():
raise ValueError
return self._elem.popleft()
def is_empty(self):
return len(self._elem) == 0
class BinTreeNode:
def __init__(self, data, left=None, right=None):
self.data = data
self.left = left
self.right = right
class BinTree(object):
def __init__(self, root=None):
self.root = root
@classmethod
def build_from(cls, node_list):
"""通过节点信息构造二叉树
第一次遍历我们构造 node 节点
第二次遍历我们给 root 和 孩子赋值
最后我们用 root 初始化这个类并返回一个对象
:param node_list: {'data': 'A', 'left': None, 'right': None, 'is_root': False}
"""
node_dict = {}
for node_data in node_list:
data = node_data['data']
node_dict[data] = BinTreeNode(data)
for node_data in node_list:
data = node_data['data']
node = node_dict[data]
if node_data['is_root']:
root = node
node.left = node_dict.get(node_data['left'])
node.right = node_dict.get(node_data['right'])
return cls(root)
"""
二叉树的先序遍历:
先访问根节点,如果有左右孩子在递归调用自身
访问左右孩子节点
"""
def preorder_trav(self, subtree):
if subtree:
print(subtree.data, end=',')
self.preorder_trav(subtree.left)
self.preorder_trav(subtree.right)
@staticmethod
def layer_trav(subtree):
cur_node = [subtree]
next_node = []
while cur_node or next_node:
for node in cur_node:
print(node.data, end=',')
if node.left:
next_node.append(node.left)
if node.right:
next_node.append(node.right)
cur_node = next_node
next_node = []
"""
因为层序遍历是按顺序访问的
所以可以用队列来实现二叉树的层序遍历
"""
@staticmethod
def layer_trav_use_queue(subtree):
q = Queue()
q.append(subtree)
while not q.is_empty():
node = q.pop()
print(node.data, end=',')
if node.left:
q.append(node.left)
if node.right:
q.append(node.right)
def reverse(self, subtree):
if subtree is not None:
subtree.left, subtree.right = subtree.right, subtree.left
self.reverse(subtree.left)
self.reverse(subtree.right)
if __name__ == '__main__':
node_list = [
{'data': 'A', 'left': 'B', 'right': 'C', 'is_root': True},
{'data': 'B', 'left': 'D', 'right': 'E', 'is_root': False},
{'data': 'D', 'left': None, 'right': None, 'is_root': False},
{'data': 'E', 'left': 'H', 'right': None, 'is_root': False},
{'data': 'H', 'left': None, 'right': None, 'is_root': False},
{'data': 'C', 'left': 'F', 'right': 'G', 'is_root': False},
{'data': 'F', 'left': None, 'right': None, 'is_root': False},
{'data': 'G', 'left': 'I', 'right': 'J', 'is_root': False},
{'data': 'I', 'left': None, 'right': None, 'is_root': False},
{'data': 'J', 'left': None, 'right': None, 'is_root': False},
]
btree = BinTree.build_from(node_list)
print('先序遍历')
btree.preorder_trav(btree.root)
print('\n')
print('层序遍历')
btree.layer_trav(btree.root)
print('\n')
print('使用队列的层序遍历')
btree.layer_trav_use_queue(btree.root)
print('\n')
btree.reverse(btree.root)
print('反转二叉树')
print('先序遍历')
btree.preorder_trav(btree.root)
print('\n')