欢迎来到杨河的博客

人生三从境界:昨夜西风凋碧树,独上高楼,望尽天涯路。 衣带渐宽终不悔,为伊消得人憔悴。 众里寻他千百度,蓦然回首,那人却在灯火阑珊处。

二叉树的实现

二叉树的实现

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

 

 

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

导航