为什么有些语言像C++;Java有内置的LinkedList数据结构吗?
许多编程语言提供内置数据结构,尽管一些数据结构,如链表,众所周知非常容易实现,因此,语言通常不将其作为内置数据结构。 一些语言,例如(as为什么有些语言像C++;Java有内置的LinkedList数据结构吗?,java,python,c++,data-structures,linked-list,Java,Python,C++,Data Structures,Linked List,许多编程语言提供内置数据结构,尽管一些数据结构,如链表,众所周知非常容易实现,因此,语言通常不将其作为内置数据结构。 一些语言,例如(asstd::list,双链接),(asLinkedList,双链接) 例如,Python的库中已经内置了多个数据结构,包括列表、元组、集合、字典(甚至不需要导入),以及集合库中的数据结构。它没有内置的LinkedList数据结构,因为在Python中,实现自己的LinkedList已经很容易了 请注意,Python列表的底层数据结构实际上是一个数组,如中所述。此
std::list
,双链接),(asLinkedList
,双链接)
例如,Python的库中已经内置了多个数据结构,包括列表、元组、集合、字典(甚至不需要导入),以及集合
库中的数据结构。它没有内置的LinkedList
数据结构,因为在Python中,实现自己的LinkedList已经很容易了
请注意,Python列表的底层数据结构实际上是一个数组,如中所述。此外,DeQuin <代码>集合是一个双端队列,它应该具有缺失的特性,因为它通常不支持中间的索引或插入(但是,索引特性自3.5以来已经添加了<代码>索引< /代码>和<代码>插入< /代码>,但是在Python 2中不存在。< /P>
似乎提供内置的
LinkedList
数据结构是多余和不必要的。为什么其他的编程语言库(如C++和java库)包括<代码> Link KEdList< /Cord>数据结构,即使它们很容易实现吗?如果是这样的话,用这些语言实现自己的链表有什么风险?我在Guido的博客上搜索过,因为我确信他写过这篇文章,但显然他并没有这么做。因此,这是基于推理(即受过教育的猜测)和记忆(可能有缺陷)的结合
让我们从结尾开始:在不知道为什么Guido没有在Python0.x中添加链表的情况下,我们至少知道为什么核心开发人员从那时起没有添加链表,即使他们已经添加了从OrderedDict
到set
的一系列其他类型
是的,我们有。简短的说法是:20多年来,没有人要求过。这些年来,几乎所有添加到内置或标准库中的内容都是(一种变体)在或上被证明是有用和流行的。例如,这就是OrderedDict
和defaultdict
的来源,以及enum
和dataclass
(基于attrs
)。对于一些其他容器类型,有各种排序的dict/set、OrderedSet、trees和try等流行的库,并且SortedContainers
和blist
都已被提议,但被拒绝,以纳入stdlib
但是没有流行的链表库,这就是为什么它们永远不会被添加的原因
因此,这就把问题带回到了一个阶段:为什么没有流行的链表库
首先,“链表”实际上不是一种类型,而是一系列类型,单链表与双链表、节点列表与句柄列表、尾部共享与否、惰性(可能通过@property
-style触发器)或严格的……以及循环列表等变体。当然,每一个都远不如整个家庭有用。你不能在接口或实现之间共享所有的东西,一个处理LISP风格<代码> CONS <代码>的接口对于C++之类的代码毫无意义,STD::清单
其次,所有不同的变体都非常容易构建。OrderedDict
之所以成为该语言的一部分,是因为人们能够证明,要正确使用它实际上非常困难。集合很容易得到正确的结果,但如果不借用DICT的幕后实现细节,就不可能进行空间优化。链表很容易得到正确的和优化。如果你想要一个,任何一个品种,你在几分钟内建成一个,你就完成了。(事实上,OrderedDict
在引擎盖下使用了一个…)
与此同时,自Python 2.3以来,尤其是自3.0以来,迭代器协议已经成为所有事情的中心范式。其他语言借用Python的生成器是有原因的,但在大多数语言中,它们并没有提供相同的好处,因为整个语言并不是围绕它们构建的。能够向前迭代任何集合,包括一个甚至还不存在的“虚拟”集合,这将为您提供无需延迟尾部共享cons列表的大部分优势。另一方面,它缺少的主要内容是方便的常数时间(变异)拼接,但缺少的一点实际上很难适应迭代器范式。(请参见itertools
了解如何操作,毕竟这只是tee
和chain
,以及这样做的感觉有多笨拙。)
(当然还有一个更复杂的迭代协议的优点,比如C++所使用的,或者甚至更好,SWIFT。双向和可变的,不可变的迭代,双链表可能更有用。但是在那里有能力和简单性之间的权衡,Python很久以前就做出了选择)。 最后,但绝对不是最不重要的,链表,特别是cons样式的尾部共享链表,是一种固有的递归数据结构。Python的理念是只有在存在固有的递归问题时才使用递归。Guido认为这类代码很少,这就是Python不做的原因,例如尾部递归消除。他不想在他的语言中使用
map
和reduce
,但一旦他想出了如何迭代而不是递归地执行这些操作,他愿意让它们保留下来。存储线性数据并不是一个固有的递归问题。树?当然,它们必须是递归的。但是名单呢?没有。我相信