确实存在各种各样的混合物。您有不与算法相关联的数据结构,有不需要(实际)数据结构的算法,但是大多数情况下,两者是打包在一起的。
编辑:正如@Doval正确指出的那样,数据结构本身没有任何关联的操作。数据结构和算法相结合的行为形成了抽象的数据类型。
没有算法的数据结构
考虑例如用于存储二维坐标的数据结构,适当地称为Point
。对于一个点,在算法上没有什么可做的,它实际上只是一个x
和y
值的容器。当然,有了这种数据结构,您现在可以在其之上添加各种算法(距离计算,凸包,具有所需功能)。
您可以想到很多数据结构,它们只是单个数据的累积。尽管这些在实践中确实经常发生,但它们并不能构成很好的教材,因为没有什么可学的,一旦您了解了,单个数据项就可以累积到一个新的数据结构中(就像您学到的一样)在上面的Point
示例之后,如果我为您提供了一个名为的出色数据结构Point3D
,它可以对3维空间做同样的事情?)
没有(真实)数据结构的算法
“真实”,因为显然每个有趣的算法都需要原始数据类型,例如整数或布尔值,因此在此上下文中我们不希望将它们视为数据结构。与上述类似,这些算法通常非常简单。特别是,它们不会带有任何复杂的状态,因为它通常进入数据结构中(请参阅下一节)。
这种算法的一个示例是计算两个数字的最大公约数。Euklid的gcd算法实际上只需要保存两个整数并对其进行操作。
一旦事情变得越来越有趣,您很快就会进入抽象数据类型的世界。例如,Eratosthenes的筛子是基于数组的。现在我们可以讨论数组是否仍然是原始数组,或者实际上,您可以讨论整数是否还不是数据结构。无论哪种方式,即使您接受了孤立存在的算法,但完全没有数据结构的算法却很无聊。
结合数据结构(又称为抽象数据类型)的算法
现在这些是有趣的,但是出于两个截然不同的原因。通常,您可以从两个方向处理这些问题:首先是数据结构,或者首先是算法。
虽然抽象数据类型是通过数据结构+算法/操作的组合来定义的,但我们通常将其重点放在其中的一种上,而将另一种视为促成因素。
数据结构,然后是算法
您将遇到抽象数据类型,这些数据类型使用起来非常简单,但是涉及或多或少的复杂算法以使其在内部工作。例如,a HashMap
使用起来很琐碎,但是涉及一个漂亮的哈希函数并处理内部的哈希冲突。但是,从您作为用户的角度来看,您关心的是它为您保留了数据,而不是为您提供服务的东西。
与下面的最后一组相反,这些数据结构不会将其用户暴露给这些算法。您无需了解或关心HashMap
s的内部哈希函数就可以使用它。(但是,要有效地使用它,您可能想知道这些事情;)
算法,然后是数据结构
另一个方向意味着您拥有一种算法,希望能够简单地使用它,但是需要内部使用数据结构来使其按预期工作。一个示例就是二进制空间分区(BSP)算法,您可以简单地Point
从一组最接近给定查询点的点中请求二维。但是,您实际上需要在内部使用树结构(甚至包括距离计算在内的其他算法)来编写算法。
通常,可以说该组中的算法使用相关的数据结构来表示其内部状态。我会争辩说,这组算法是最多样化的,您会发现许多适合这种通用方案的算法。就观点而言,我们认为它们很有趣,因为它们为我们做了一些事情(例如排序),并且不太在意数据保存部分。
紧密相关的数据结构和算法
最后,您拥有数据结构,这些数据结构与直接对应于它们的算法非常相关。一个典型的例子是一棵二叉树,当您想对它进行有意义的处理时,它会强制您执行树遍历算法的主题(深度优先,宽度优先等)。
对于这些情况,我们经常更改结果抽象数据类型的视图重点。有时,您关心树的结构,几分钟后,您关心的是能够在树上运行查找操作,然后您想知道是否删除节点,然后马上考虑结构的外观。尽管上述所有其他部分也都适用,但例如,当您将数据存储到中或从中检索数据Map
时,或者在对链表进行排序时,这并不是您要关注的重点。