我读过很多文章,其中提到当我们必须在集合中间执行插入/删除时,链表会表现得很好。但我有一个疑问。我正在学习数据结构,如果我的理解不正确,请告诉我。
假设我们在列表中有10个项目
索引:-0|1|2|3|4|5|6|7|8|9
项目:-A|I|Z|S|J|T|V|J|A|T
我想删除索引6中的项目,意思是"V",然后进一步的项目,我们必须向上移动一个级别。我知道,当我们有很大的清单时,这种转变是一种代价高昂的操作。
在链表的情况下,我们不必移动项目,因为我们可以将上一个和下一个指针更改为新节点。
示例-
头节点A=>D=>Z=>S=>C=>W=>M=>Q=>E=>T
现在假设我们必须删除W,那么根据我的理解,我们必须从头节点(A(遍历到W。所以,这也是一个昂贵的操作,比如在列表中,我们在删除后移动项目。那么这个场景是如何利用链表而不是列表的呢
只有当您已经引用了要插入或删除的节点时,在链表中间插入和删除才会很快,因此您不需要遍历列表才能找到它。
在C#中,这使得LinkedList
集合在通过引用(这样您就不必找到它们(或通过另一个集合或索引标识对象时非常有用,并且列表中的每个项都可以引用其LinkedListNode
。
使用LinkedList
的一个很好的例子是LRU缓存——该缓存由一个字典和一个链表组成。当你在字典中找到一个条目时,你会移动到列表的前面。如果项目引用了其LinkedListNode
,那么无论列表最初在哪里,都可以在恒定时间内将其移动到前面。
在不公开节点类的Java中,LinkedList
集合基本上是无用的。
链表的优点是元素可以无限期地添加到链表中(取决于可用内存(,而数组最终会被填充或必须调整大小(这是一项成本高昂的操作,但并不总是可能的(。
当列表中的项目总数未知并且不需要对元素进行随机访问时,链表最适合使用。当我们知道列表中项目数量的上限并且需要随机访问元素时,数组更适合。
此外,如果您还不知道要在数组中删除的项的索引。您需要找到该元素,然后执行转换。在链表中,您只需要找到元素并删除指针,就不需要移动元素。