IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 数据结构--树型结构 -> 正文阅读

[数据结构与算法]数据结构--树型结构

树型结构

基本概念

在这里插入图片描述

  • (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 "不是"))
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-07-04 23:13:18  更:2022-07-04 23:15:57 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/22 12:01:35-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码