# 二叉树的实现

### 1.二叉树的节点类

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.构建二叉树

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')

posted on 2019-08-25 13:05  橘子味的猫啊  阅读(...)  评论(...编辑  收藏