Python 数据结构之二叉树的实现

1、基本概念

二叉树 是一种简单的树形结构,是每个节点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树是一种递归结构。
二叉树的基本概念

  • 空树:不包含任何节点的二叉树成为空树。只包含一个节点的二叉树称为一个单点树。
  • 父节点和子节点:一颗二叉树的根节点称为该数的子树根节点的父节点,与之对应的,子数的根节点称为二叉树树根节点的子节点。注意父节点和子节点是相对的。
  • 叶子节点:在二叉树中没有子节点的节点称为叶子节点。
  • 分支节点:只有存在子节点的节点都是分之节点。
  • 度数:一个节点的子节点的个数称为该节点的度数。即 叶子节点的度数永远为0,分之节点的度数为1或2。
  • 二叉树的层:二叉树是一种层次结构,根节点称为二叉树的0层,从根节点到任一节点的路径长度就是该节点所在的层数,也称为该节点的层数。
  • 二叉树的高度:也称为深度,就是树中节点的最大层数。

二叉树的性质

  • 性质1: 在二叉树的第i层上至多有2^(i-1)个结点(i>0)
  • 性质2: 高度为h的二叉树至多有2^h - 1个结点(h>0)
  • 性质3: 对于任意一棵二叉树,如果其叶结点数为N0,而度数为2的结点总数为N2,则N0=N2+1;
  • 性质4:具有n个结点的完全二叉树的深度必为 log2(n+1)
  • 性质5:对完全二叉树,若从上至下、从左至右编号,则编号为i 的结点,其左孩子编号必为2i,其右孩子编号必为2i+1;其双亲的编号必为i/2(i=1 时为根,除外)

满二叉树:如果二叉树中所有分支节点的度数都是2,这样的二叉树称为满二叉树。
完全二叉树:若设二叉树的高度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第h层有叶子结点,并且叶子结点都是从左到右依次排布,这就是完全二叉树。
二叉树的遍历:

深度优先遍历:
	深度优先搜索(Depth First Search)是沿着树的深度遍历树的节点,尽可能深的搜索树的分支。
	那么深度遍历有重要的三种方法。这三种方式常被用于访问树的节点,它们之间的不同在于访问每个节点的次序不同。
	这三种遍历分别叫做先序遍历(preorder),中序遍历(inorder)和后序遍历(postorder)。
	先序遍历:在先序遍历中,先访问根节点,然后递归使用先序遍历访问左子树,再递归使用先序遍历访问右子树。即 根节点->左子树->右子树
	中序遍历:在中序遍历中,递归使用中序遍历访问左子树,然后访问根节点,最后再递归使用中序遍历访问右子树。即 左子树->根节点->右子树
	后序遍历:在后序遍历中,先递归使用后序遍历访问左子树和右子树,最后访问根节点。即 左子树->右子树->根节点
   
广度优先遍历:
	是按路径长度由近到远地访问节点。也就是按二叉树的层次逐层访问树中各个节点,这种遍历不能写成一个递归过程。

2、二叉树基于Python 列表的简单实现

# 二叉树基于Python语言list的实现

class BinTreeListWay(object):
    """
    二叉树类
    """
    def __init__(self, data, left=None, right=None):
        self.__bintree = [data,left, right]

    def is_empty(self):
        """
        判断二叉树是否为空
        """
        return self.__bintree == None
    
    def root(self):
        """
        返回根节点
        """
        return self.__bintree[0]

    def left(self):
        return self.__bintree[1]

    def right(self):
        return self.__bintree[2]

    def set_root(self, data):
        """
        设置根节点
        """
        self.__bintree[0] = data

    def set_left(self, data):
        self.__bintree[1] =data

    def set_right(self, data):
        self.__bintree[2] = data

    def show(self):
        """
        返回二叉树
        """
        return self.__bintree

if __name__ == "__main__":
    d_tree = BinTreeListWay('D', 'F', 'G')
    e_tree = BinTreeListWay('E', 'I', 'H')
    c_tree = BinTreeListWay('C', d_tree.show(), e_tree.show())
    a_tree = BinTreeListWay('A', 'B')
    a_tree.set_right(c_tree.show())
    print(a_tree.show())

3、二叉树基于Python自建类的实现

# 二叉树基于Python语言面自建类的实现

class Node(object):
    """
    节点类
    """
    def __init__(self, data, left=None, right=None):
        self.data = data
        self.left = left
        self.right = right


class BinTreeClassWay(object):
    """
    二叉树类
    """
    def __init__(self, root=None):
        self.root = root
    
    def is_empty(self):
        """
        判断二叉树是否为空
        """
        return self.root == None

    def add(self, data):
        """
        添加节点,此方法无法控制将节点挂在到那颗子树,也就意味着它最终形成的二叉树为完全二叉树或满二叉树
        """
        # 实例化一个新的节点对象
        node = Node(data)
        # 如果树是空的,则对根节点数据元素赋值
        if self.root == None:
            self.root = node
        else:
            # 创建一个存放节点的队列
            queue = []
            queue.append(self.root)
            # 对已有的节点按层次进行遍历
            while queue:
                # 弹出队列的第一个节点
                head = queue.pop(0)
                if head.left == None:
                    head.left = node
                    return
                elif head.right == None:
                    head.right = node
                    return
                else:
                    #如果左右子树都不为空,加入队列继续判断
                    queue.append(head.left)
                    queue.append(head.right)

    # 基于深度优先遍历
    def preorder(self, bin_tree):
        """
        先序遍历方法: 根节点->左子树->右子树
        """
        if bin_tree == None:
            return
        print(bin_tree.data)
        self.preorder(bin_tree.left)
        self.preorder(bin_tree.right)
    
    # 基于深度优先遍历
    def inorder(self, bin_tree):
        """
        中序遍历方法: 左子树->根节点->右子树
        """
        if bin_tree == None:
            return
        self.preorder(bin_tree.left)
        print(bin_tree.data)
        self.preorder(bin_tree.right)
    
    # 基于深度优先遍历
    def postorder(self, bin_tree):
        """
        后序遍历方法: 左子树->右子树->根节点
        """
        if bin_tree == None:
            return
        self.preorder(bin_tree.left)
        self.preorder(bin_tree.right)
        print(bin_tree.data)

    # 基于广度优先遍历
    def breadth_first_travel(self, bin_tree):
        """
        广度优先遍历
        """
        if bin_tree == None:
            return
        # 该方法和 add 方法中的插入元素类似
        queue = []
        queue.append(bin_tree)
        while queue:
            node = queue.pop(0)
            print(node.data)
            if node.left:
                queue.append(node.left)
            if node.right:
                queue.append(node.right)

    def show(self):
        """
        返回二叉树
        """
        return self.root

if __name__ == "__main__":
    bin_tree = BinTreeClassWay()
    bin_tree.add('A')
    bin_tree.add('B')
    bin_tree.add('C')
    bin_tree.add('D')
    bin_tree.add('E')
    bin_tree.add('F')
    bin_tree.add('G')
    print('先序遍历')
    bin_tree.preorder(bin_tree.show())
    print('中序遍历')
    bin_tree.inorder(bin_tree.show())
    print('后序遍历')
    bin_tree.postorder(bin_tree.show())
    print('广度优先遍历')
    bin_tree.breadth_first_travel(bin_tree.show())
发布了264 篇原创文章 · 获赞 202 · 访问量 110万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章