zoukankan      html  css  js  c++  java
  • 二叉树的实现

    二叉树的实现

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

     

    杨河
  • 相关阅读:
    中值滤波器(平滑空间滤波器)基本原理及Python实现
    均值滤波器(平滑空间滤波器)基本原理及Python实现
    使用bibtex为latex论文添加参考文献
    【Linux】日志
    【Linux】常用命令
    【Oracle】查看表大小
    【Oracle】to_date兼容YYYYMMDDHH24MISS与YYYY-MM-DD HH24:MI:SS
    【Mybatis】Lexical error
    【JS】上传插件配置
    【2020-10-06】年年岁岁做计划,岁岁年年完不成!
  • 原文地址:https://www.cnblogs.com/yang-he/p/11407626.html
Copyright © 2011-2022 走看看