二叉树的实现

孤人 提交于 2019-11-28 12:44:16

二叉树的实现

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

 

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!