数据结构--树型结构

树型结构

基本概念

在这里插入图片描述

  • (1)根节点(Root):树顶端的节点称为根节点,一般一棵树只有一个根节点。
  • (2)双亲节点(Parent Node):三角形阴影中的 D 是 H 和 I 的双亲节点。同理,A 是 B 和 C 的双亲节点。
  • (3)孩子节点(Child Node):与双亲节点相反,H 和 I 是 D 的孩子节点。
  • (4)节点的度(Degree):节点拥有的子树的数目。例如,节点 D 的度为 2,节点 E 的度为 1。
  • (5)叶子节点(Leaf Node):度为 0 的节点称为叶子节点。
  • (6)兄弟节点( Brother Node):一个双亲节点下的孩子节点互为兄弟节点。例如,H 和 I 为兄弟节点。
  • (7)节点层次(Level):根节点为第一层,它的子节点为第二层,依次向下递推,如H、 I、J 均为第四层。
  • (8)树的深度(Level of Tree):树中节点的最大层次,如图中树的深度为 3。
  • (9)树的度(Degree of Tree):树中节点的度的最大值,如图中树的度为 2。

动态查看树的结构

(1)根节点(Root):树顶端的节点称为根节点,一般一棵树只有一个根节点。
(2)双亲节点(Parent Node):三角形阴影中的 D 是 H 和 I 的双亲节点。同理,A 是 B 和 C 的双亲节点。
(3)孩子节点(Child Node):与双亲节点相反,H 和 I 是 D 的孩子节点。
(4)节点的度(Degree):节点拥有的子树的数目。例如,节点 D 的度为 2,节点 E 的度为 1。
(5)叶子节点(Leaf Node):度为 0 的节点称为叶子节点。
(6)兄弟节点( Brother Node):一个双亲节点下的孩子节点互为兄弟节点。例如,H 和 I 为兄弟节点。
(7)节点层次(Level):根节点为第一层,它的子节点为第二层,依次向下递推,如H、 I、J 均为第四层。
(8)树的深度(Level of Tree):树中节点的最大层次,如图中树的深度为 3。
(9)树的度(Degree of Tree):树中节点的度的最大值,如图中树的度为 2。

二叉树

二叉树(Binary Tree)是一种特殊的树结构,它的每个节点最多有两个子树,也就是树的度不大于2的。

  • (1)完美二叉树(Perfect Binary Tree):除了叶子节点之外的每一个节点都有两个孩子节点 , 每一层(包含最后一层)都被完全填充
  • (2)完全二叉树(Complete Binary Tree):除了最后一层之外的每一层都被完全填充,并且所有节点都保持向左对齐。
  • (3)完满二叉树(Full Binary Tree):除了叶子节点之外的每一个节点都有两个孩子节点。

遍历

  1. 先序遍历(Pre-order Traversal)是先访问根节点,然后访问左子树,最后访问右子树。访问左子树也是按照这个规则,先访问双亲节点,然后访问左节点,最后访问右节点。

  2. 中序遍历(In-order Traversal)是从根节点开始,首先访问左子树,然后访问根节点,最后访问右子树。

  3. 后序遍历(Post-order Traversal)是先访问左子树,然后访问右子树,最后访问根节点。

完整代码实现

# 创建结点对象
class TreeNode(object):
    def __init__(self, value, left=None, right=None):
        if left is not None and not isinstance(left, TreeNode):
            raise ValueError('左孩子结点必须是结点类')
        if right is not None and not isinstance(right, TreeNode):
            raise ValueError('左孩子结点必须是结点类')
        self.value = value  # 结点值
        self.left = left    # 左孩子结点
        self.right = right  # 右孩子结点
    
    def __repr__(self):
        return 'TreeNode({})'.format(self.value)
    
    def insert_left(self,value):
        # 在左边插入新的结点
        if self.left == None:
            self.left = TreeNode(value)
        else:
            # 若结点存在,把原来结点放到新结点的左孩子结点
            tmp = TreeNode(value)
            tmp.left = self.left
            self.left = tmp
            
    def insert_right(self,value):
        # 在右边插入新的结点
        if self.right == None:
            self.right = TreeNode(value)
        else:
            # 若结点存在,把原来结点放到新结点的右孩子结点
            tmp = TreeNode(value)
            tmp.right = self.right
            self.right = tmp
            
    def pre_order_traversal(self):
        # 先序遍历:根-左-右
        result = [self.value]   # 先访问根结点
        if self.left:
            # 再访问左边子树,在子树里面递归使用先序遍历里面的结点
            result += self.left.pre_order_traversal()
        if self.right:
            # 最后访问右边子树
            result += self.right.pre_order_traversal()
        return result
    
    def in_order_traversal(self):
        # 中序遍历:左-根-右
        result = []
        if self.left:
            # 遍历左边子树
            result += self.left.in_order_traversal()
        # 接着访问根结点
        result.append(self.value)
        if self.right:
            # 遍历右边子树
            result += self.right.in_order_traversal()
        return result
    
    def post_order_traversal(self):
        # 后序遍历:左-右-根
        result = []
        if self.left:
            result += self.left.post_order_traversal()
        if self.right:
            result += self.right.post_order_traversal()
        result.append(self.value)
        return result

运行结果

# 创建二叉树例子
binary_tree = TreeNode('A')
binary_tree.insert_left('B')
binary_tree.insert_right('C')
binary_tree.left.insert_left('D')
binary_tree.left.insert_right('E')
binary_tree.right.insert_left('F')
binary_tree.right.insert_right('G')
# 根据三种遍历方式,访问二叉树的数据
res = binary_tree.pre_order_traversal()
print("先序遍历", "->".join(res))
res = binary_tree.in_order_traversal()
print("中序遍历", "->".join(res))
res = binary_tree.post_order_traversal()
print("后序遍历", "->".join(res))

先序遍历 A->B->D->E->C->F->G
中序遍历 D->B->E->A->F->C->G
后序遍历 D->E->B->F->G->C->A

练习:判断是否为完美二叉树

def if_perfect(tree):
    # 根据完美二叉树定义,它的叶子数量=2^(树的深度-1)
    max_depth = 0  # 树最大的深度
    leaf_count = 0       # 叶子数量
    size = 0             # 结点数量
    current_nodes = [tree]    
    while len(current_nodes) > 0:
        max_depth += 1
        next_nodes = []        
        for node in current_nodes:
            size += 1
            if node.left is None and node.right is None:
                leaf_count += 1  # 根据定义,没有孩子结点就是叶子结点
            if node.left is not None:
                next_nodes.append(node.left)
            if node.right is not None:
                next_nodes.append(node.right)
        current_nodes = next_nodes                
    print("叶子的深度{},叶子数量{},因此它{}完美二叉树".format(
        max_depth,leaf_count,
        "是" if leaf_count == 2 ** (max_depth-1) else "不是"))

更多内容

想获取完整代码或更多相关图的算法内容,请查看我的书籍:《数据结构和算法基础Python语言实现》

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值