引入
树(Tree)是一种非线性结构。其内部数据并不是以线性
的方式存储在内存中,而是以一种层级
的关系保存的内存当中。
这种层级是什么意思呢? 举个例子,现实生活中其实有很多关系都是一层级的方式存在的。比较经典的有以下几种
公司中的组织架构关系:
家族族谱
比赛的对阵表
植物的根茎
以上几种都是按照树形结构组织数据的绝好例子。
树の定义
接下来看一下在计算机科学中,树(Tree)是如何被定义的。树(Tree)
是将一组被称为结点(Node)
的元素按照层次结构的方式组织而成。在这个层次结构最顶端的结点称为根
, 与根直接相连的结点称为根的子结点
。通常子节点本身也可以拥有属于它们自己的子结点,而将这些子结点链接起来的叫做边(Edge)
用图像来表示一棵普通的树形结构如下图所示:
相关术语
结点Node
一棵树是由1个或多个结点(Node)通过分支链接起来的结构。每个结点中都包含一个value以及指向它的子结点的分支(代码中用指针表示)。比如上图中的60、40、51都是一个个的结点
根结点
树中最顶端的结点。上图中的60就是树的根结点,这个结点是树中其它所有结点的祖先结点
父结点&子结点
与分支结点直接相连的结点被称为父结点。比如上图中51是80和70的父结点,同样40也是32和16的父结点等。反过来说80和70也是51的子结点
兄弟结点
拥有同一个父结点的结点们被称为兄弟结点, 比如上图中32和16、80和70、71和14都是兄弟关系
叶子结点
没有子结点的结点被称为叶子结点。比如图中绿色的结点。
树的高度
高度这个概念是属于树的一个属性。一个树的高度是根节点到叶子结点的路径上所包含最长的分支数量。比如上图中根节点到叶子结点最长的路径是60-40-32-71-40,包含4条分支,因为树的高度为4。
结点深度
深度的概念是属于某一结点的属性,我们通常会说某某结点的深度。深度的定义是此结点到根节点的路径包含的分支数量。比如上图中17的深度为3,而根节点的深度为0。
实现一个简单的树形结构
上面提到过,树的每个结点中都包含一个自身value,以及指向它子结点的分支。因此我们可以简单的实现一个树结点如下:
通过上面的TreeNode,可以创建一个简单的树形结构,如下所示:
可以看到在根结点root
下只有一个子结点bNode
,而在bNode
下有三个子结点。因此上面构造的树形结构用图形来表示如下:
树的应用
- 用户界面
做过Android开发的童鞋都会对窗口
这个概念有一定的印象。在图形用户界面中,窗口就是按照树这种结构层次来组织的;除了顶部窗口之外,每个窗口都有一个父窗口,而每一个子窗口也都可以有自己的子窗口。 - 文件系统
在实现某操作系统中的文件系统时,也是按照树形结构来实现的。也就是说除了根目录之外,每一个目录都可以有多个字目录,而每一个子目录也都有一个上级目录。 - 表达式处理(后续章节会讲解)
表达式处理是编译器或者计算器经常用到的操作。它是一种将表达式的操作数和操作符按照层次的结构组织到一棵二叉树中,然后对这个二叉树进行相应的遍历操作从而实现数学计算的功能。 - 优先级队列(后续章节会讲解)
它采用一棵二叉树来记录集合中的哪个元素拥有下一个最高的优先级。在这一节中将了解到与将一组数据全部排序相比,优先级队列提供了一种更好的方案。