您的位置:首页 > 编程语言 > Python开发

基于Problem Solving with Algorithms and Data Structures using Python的学习记录(6-1)——Tree

2017-04-05 14:31 483 查看

6.1.目标

要理解树数据结构是什么,以及如何使用它。

查看树如何用于实现 map 数据结构。

使用列表实现树。

使用类和引用来实现树。

实现树作为递归数据结构。

使用堆实现优先级队列。

6.2.树的例子

现在我们已经研究了线性数据结构,如栈和队列,并且有一些递归的经验,我们将看一个称为树的常见数据结构。树在计算机科学的许多领域中使用,包括操作系统,图形,数据库系统和计算机网络。树数据结构与他们的植物表亲有许多共同之处。树数据结构具有根,分支和叶。自然界中的树和计算机科学中的树之间的区别在于树数据结构的根在顶部,其叶在底部。

在我们开始研究树形数据结构之前,让我们来看几个常见的例子。我们树的第一个例子是生物学的分类树。Figure 1 展示了一些动物的生物分类的实例。从这个简单的例子,我们可以了解树的几个属性。此示例演示的第一个属性是树是分层的。通过分层,我们的意思是树的层次结构,更接近顶部的是抽象的东西和底部附近是更具体的东西。层次结构的顶部是 Kingdom,树的下一层(上面的层的“Children”)是 Phylum,然后是 Class,等等。然而,无论我们在分类树中有多深,所有的生物仍然是 animals。

注意,你可以从树的顶部开始,并沿着圆圈和箭头一直到底部的路径。在树的每一层,我们可能问自己一个问题,然后遵循与我们的答案一致的路径。例如,我们可能会问,“这个动物是Chordate(脊椎动物)还是Arthropod(节肢动物)?”如果答案是“Chordate”,那么我们遵循这条路径,问“这个Chordate是 Mammal(哺乳动物)吗?”如果不是,我们就卡住了这个简化的例子)。当我们在哺乳动物那层时,我们问“这个哺乳动物是Primate(灵长类动物)还是 Carnivore(食肉动物)?”我们可以遵循以下路径,直到我们到达树的最底部,在那里我们有共同的名字。

树的第二个属性是一个节点的所有子节点独立于另一个节点的子节点。例如,Felis 有属于 Domestica 和 Leo 的孩子。Musca 也有一个名为 Domestica 的孩子,但它是一个不同的节点,并独立于 Felis 的 Domestica孩子。这意味着我们可以改变作为 Musca 的孩子的节点而不影响 Felis 的孩子。

第三个属性是每个叶节点是唯一的。我们可以指定从树的根到唯一地识别动物王国中的每个物种的叶的路径;例如,Animalia→→Chordate→→Mammal→→Carnivora→→Felidae→→Felis→→Domestica。

你可能每天使用的树结构的另一个示例是文件系统。在文件系统中,目录或文件夹被构造为树。Figure 2 说明了 Unix文件系统层次结构的一小部分。



文件系统树与生物分类树有很多共同之处。你可以遵循从根目录到任何目录的路径。 该路径将唯一标识该子目录(及其中的所有文件)。 树的另一个重要属性来源于它们的层次性质,你可以将树的整个部分(称为子树)移动到树中的不同位置,而不影响层次结构的较低级别。 例如,我们可以使用整个子树 /etc/,从根节点分离,并重新附加在 usr/ 下。 这将把 httpd 的唯一路径名从 /etc/httpd 更改为 /usr/etc/httpd,但不会影响 httpd 目录的内容或任何子级。

树的最后一个例子是网页。 以下是使用HTML编写的简单网页的示例。 Figure 3 展示了用于创建页面的每个 HTML 标记的树。

<html xmlns="http://www.w3.org/1999/xhtml"
xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=utf-8" />
<title>simple</title>
</head>
<body>
<h1>A simple web page</h1>
<ul>
<li>List item one</li>
<li>List item two</li>
</ul>
<h2><a href="http://www.cs.luther.edu">Luther CS </a><h2>
</body>
</html>




HTML源代码和伴随源的树说明了另一个层次结构。请注意,树的每个级别都对应于HTML标记内的嵌套级别。源中的第一个标记是 ,最后一个是 页面中的所有其余标记都是成对的。 如果你检查,你会看到这个嵌套属性在树的所有级别都是 true。

6.3.词汇和定义

我们已经看了树的示例,我们将正式定义树及其组件。

节点

节点是树的基本部分。它可以有一个名称,我们称之为“键”。节点也可以有附加信息。我们将这个附加信息称为“有效载荷”。虽然有效载荷信息不是许多树算法的核心,但在利用树的应用中通常是关键的。



边是树的另一个基本部分。边连接两个节点以显示它们之间存在关系。每个节点(除根之外)都恰好从另一个节点的传入连接。每个节点可以具有多个输出边。



树的根是树中唯一没有传入边的节点。在 Figure 2 中,/ 是树的根。

路径

路径是由边连接节点的有序列表。例如,Mammal→→Carnivora→→Felidae→→Felis→→Domestica是一条路径。

子节点

具有来自相同传入边的节点 c 的集合称为该节点的子节点。在 Figure 2中,节点 log/,spool/ 和 yp/ 是节点 var/ 的子节点。

父节点

具有和它相同传入边的所连接的节点称为父节点。在 Figure 2 中,节点 var/ 是节点 log/,spool/ 和 yp/ 的父节点。

兄弟

树中作为同一父节点的子节点的节点被称为兄弟节点。节点 etc/ 和 usr/ 是文件系统树中的兄弟节点。

子树

子树是由父节点和该父节点的所有后代组成的一组节点和边。

叶节点

叶节点是没有子节点的节点。 例如,人类和黑猩猩是 Figure 1 中的叶节点。

层数

节点 n 的层数为从根结点到该结点所经过的分支数目。 例如,图1中的Felis节点的级别为五。根据定义,根节点的层数为零。

高度

树的高度等于树中任何节点的最大层数。 Figure 2 中的树的高度是 2。

现在已经定义了基本词汇,我们可以继续对树的正式定义。 事实上,我们将提供一个树的两个定义。 一个定义涉及节点和边。 第二个定义,将被证明是非常有用的,是一个递归定义。

定义一:树由一组节点和一组连接节点的边组成。树具有以下属性:

树的一个节点被指定为根节点。

除了根节点之外,每个节点 n 通过一个其他节点 p 的边连接,其中 p 是 n 的父节点。

从根路径遍历到每个节点路径唯一。

如果树中的每个节点最多有两个子节点,我们说该树是一个二叉树。

Figure 3 展示了适合定义一的树。边上的箭头指示连接的方向



定义二:树是空的,或者由一个根节点和零个或多个子树组成,每个子树也是一棵树。每个子树的根节点通过边连接到父树的根节点。

Figure 4 说明了树的这种递归定义。使用树的递归定义,我们知道 Figure 4 中的树至少有四个节点,因为表示一个子树的每个三角形必须有一个根节点。 它可能有比这更多的节点,但我们不知道,除非我们更深入树。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐