数据结构与算法(Python)——常见数据结构Part4(二叉树)

本文介绍了树的基本概念,包括直观感受、定义、相关术语,并重点讲解了二叉树的性质,如层序遍历、深度优先遍历等。此外,还提到了二叉树在逆波兰式计算中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

写在前面

在上一节part3我们熟悉队列结构,本节将熟悉应用广泛的树结构。我们的目的是快速了解他们,对于它们涉及到的复杂的数据结构和算法,在这里并不全部展开,留在后期详述。

1. 树

1.1 树的直观感受

树是一个广泛应用的数据结构,即使未开始学习这个数据结构,我们在生活或者计算机中已经和它打交道好久了。首先让我们看几个树形的应用例子(图片来自What is the real life application of tree data structures?):

Windows文件夹
这里显示的是Windows系统下文件夹的目录结构,从src目录开始,整个目录结构构成一棵树(使用Windows命令tree可以查看文件目录结构)。

Linux文件系统

上图展现的是Linux文件系统构成的一棵树。

Html文档树

上图图展现的是HTML文档树,文档结点html及其下的其他结点构成了一棵树结构。

井字棋树形结构

上图展示的是井字棋游戏中,人机对战时,机器从当前棋局状态推算出的下一状态构成的树形结构。

例子还有更多,通过上面的例子,我们已经对树形结构有了一个直观感受。下面我们看下计算中如何定义这个数据结构。

1.2 树的定义

在数据结构中,树被定义为这样一种结构:

  • 在树中有一个特殊的结点,称作根结点(Root Node),他没有父结点或者称为前驱结点(predecessor)
  • 在树中出了根以外,每个结点都有一个父结点。
  • 树中所有结点有0个后者多个后继结点(successors)

需要注意的是树与之前学习的数组、链表、栈以及队列不同,它不是一种线性结构,而是一种层次结构(hierarchical structure )

数据结构中的树,抽象表示为(图片来自DATA STRUCTURES-TREE):

树形结构

1.3 树相关的术语

了解树相关的术语对于后续学习很有必要,涉及到的术语包括下列内容(术语部分图片均来自DATA STRUCTURES-TREE)。

1) 根结点(Root)、孩子结点(Child)、父结点(Parent)
根结点及其他结点

在上面的图中A结点称之为树的根结点,它是树形开始的起点;在树中一个结点的后继称之为这个结点的孩子结点,同时这个结点本身称之为它的孩子结点的父结点,例如图中根结点A有两个孩子结点B和C,B和C有一个共同的父结点A。结点K的父结点是G,同时G的父结点是C,可以看出这种层次关系。
2) 兄弟结点(Siblings)
兄弟结点

同一个父结点的孩子结点之间的关系称之为兄弟结点,例如杀那个图中D、E、F结点称之为兄弟结点,它们共同的父结点为B;G和H结点也称之为兄弟结点,它们共同的父结点为C。

3) 叶子结点(Leaf node)、 内部和外部结点(Internal and external Nodes)

至少有一个孩子结点的结点称之为内部结点(Internal nodes),一个孩子结点都没有的结点称之为孩子结点(Leaf node),也称之为外部结点(External node)或者终端结点(Terminal Node)。

内部结点

上面的图中亮色显式的都是内部结点,暗色显式的都是叶子结点。
4) 边(Edge)
边是连接两个结点的这条链接,如下图所示:

边

5) 入度(In Degree)和出度(Out Degree)
树中指向一个结点的边的数目称之为结点的入度,从一个结点指出的边的数目称之为结点的出度。根结点的入度总是为0,叶子结点的出度总是为0。

入度和出度

图中A结点的入度为0,出度为2;B结点的入度为1,出度为3;F结点的入度为1,出度为0。

注意,很多教材或者网站,在使用这个概念时并没有区分入度和出度,将出度,也就是结点拥有的子树数量称之为结点的度。

6) 层次(Level)
在树中根结点作为开始层,一般记为0,根结点的孩子结点记为层次1,依次类推,下一层记为2,…。注意某些情形下,根结点层次也可能记为从1开始。

tree Level

7) 高度(Height)
结点的高度定义为从叶子结点到这个结点的最长路径中边的数量。叶子结点的高度记为0。树的高度定义为根结点的高度。

树的高度

8) 深度(Depth)
树中从根结点到指定结点的路径上边的数量称为这个指定结点的深度。根结点的深度定义为0。一棵树的深度定义为从根结点到叶子结点的所有深度中的最大值。
深度值

9) 路径(Path)
树中从一个结点到另一个结点的所有边和结点称之为路径,路径的长度为其中结点的数量。

路径

例如上图中,结点A和J之间路径为: A-B-E-J,长度为4。

10) 子树(Subtree)
在树中,当前结点的孩子结点及孩子结点的后继构成的树,称之为当前结点的子树。这个概念是递归的。

子树

上面的图中结点A有两个子树,结点B有3个子树。

1.4 树的种类

树是数据结构学科中广泛应用,有着多个变种的重要数据结构。其中既有简单的二叉树结构,也包括AVL(一种自平衡的二叉搜索树)、RBT(红黑树)、BTree(一种允许有多个孩子结点的二叉搜索树)等复杂的数据结构,完整的列表可以查看wiki-tree

在常见数据结构部分,本节我们重点熟悉二叉树(binary trees)二叉搜索树( binary search trees )堆(Heap)三种类型的树,对于其他更为复杂的数据结构,我们将留在高级数据结构部分学习

2. 二叉树

二叉树是每个结点最多有两个孩子的树,是一种常见的树形。例如下图所示为一个二叉树:

二叉树

2.1 二叉树的性质

了解二叉树的性质,对于分析二叉树形态、算法复杂度很有帮助,下面简述几个重要性质,参考自二叉树性质

1) 性质1 二叉树第i层上的结点数目最多为 2i1(i1) 2 i − 1 ( i ≥ 1 )
第一层为根结点,i=1,此时满足上述公式;可以通过归纳法证明上述公式,证明留给读者自行证明。

2) 性质2 深度为k的二叉树至多有 2k1(k1) 2 k − 1 ( k ≥ 1 ) 个结点
由性质1, 求和可得: 20+21++2k1=2k1 2 0 + 2 1 + … + 2 k − 1 = 2 k − 1

3) 性质3 在任意-棵二叉树中,若终端结点的个数为 n0 n 0 ,度为2的结点数为 n2 n 2 ,则 no

### 关于湖南工学院数据结构课程的信息 #### 课程概述 数据结构作为计算机科学的核心基础课程,在培养学生的算法思维和编程能力方面起着至关重要的作用。该课程旨在帮助学生掌握不同类型的数据组织方式及其相应的处理方法,从而能够有效地解决复杂的计算问题。 #### 教学大纲 根据一般高校的教学安排,数据结构课程通常会覆盖以下几个主要内容: - **基本概念**:介绍什么是数据结构以及其重要性;解释线性和非线性的区别。 - **数组链表**:探讨静态分配内存的方式——数组,动态管理存储空间的技术——单向/双向循环链表等。 - **栈和队列**:研究先进先出(FIFO) 和 后进先出(LIFO) 的抽象数据类型实现机制。 - **形结构**:深入理解二叉树、平衡查找(BSTs),红黑(RBTrees), AVL Trees, B-Trees 等高级主题。 - **图论基础**:学习顶点(vertex)/(edge)表示法,连通分量检测,最短路径寻找等问题求解技巧。 - **哈希表**:探索散列表(hash table)的工作原理及时空复杂度特性[^1]。 #### 推荐参考书目 对于希望进一步深入了解这门学科的学生来说,可以考虑阅读以下几本书籍来辅助课堂学习: - *《Introduction to Algorithms》* by Thomas H. Cormen et al. 这本书被广泛认为是关于算法设计的经典之作,它不仅涵盖了各种常见数据结构形式,而且提供了详尽的性能分析案例。 - *《Data Structures and Algorithm Analysis in C++ (Fourth Edition)》* by Mark Allen Weiss 此版本特别适合那些已经具备一定C++ 编程经验的学习者,书中通过丰富的实例演示了如何运用面向对象的思想构建高效能的应用程序。 - *《Algorithms, Part I & II》* by Robert Sedgewick and Kevin Wayne 这两部作品由Coursera平台上的同名公开课改编而成,它们以视频讲座配合练习的形式呈现给读者,非常适合自学使用[^2]。 #### 实验指导建议 为了巩固理论知识并提高实践动手能力,教师可能会布置一系列实验项目让学生完成。这些活动可能包括但不限于: - 设计简单的命令行界面应用程序,用于展示不同种类容器类的功能差异; - 使用图形化开发环境创建可视化组件,直观感受堆排序过程中的元素交换现象; - 构建小型数据库管理系统原型,体验索引建立对查询效率的影响程度; - 开发社交网络模拟器,测试广度优先搜索算法在大规模无向图上运行的表现效果。 ```python class Node: def __init__(self, value=None): self.value = value self.left_child = None self.right_child = None def insert(root, key): if root is None: return Node(key) elif key < root.value: root.left_child = insert(root.left_child, key) else: root.right_child = insert(root.right_child, key) return root # Example usage of binary search tree insertion function root = None keys = [50, 30, 70, 20, 40, 60] for k in keys: root = insert(root, k) print("Binary Search Tree constructed.") ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值