二叉树的实现
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(' ') print('层序遍历') btree.layer_trav(btree.root) print(' ') print('使用队列的层序遍历') btree.layer_trav_use_queue(btree.root) print(' ') btree.reverse(btree.root) print('反转二叉树') print('先序遍历') btree.preorder_trav(btree.root) print(' ')