我使用了很多列表和数组,但我还没有遇到一个场景,数组列表不能像链表一样容易使用,如果不是更容易的话。我希望有人能给我一些例子,说明什么时候链表明显更好。


当前回答

到目前为止,数组是使用最广泛的数据结构。然而,链表以其独特的方式被证明是有用的,而数组是笨拙的——或者至少可以说是昂贵的。

链表在大小可变的情况下,对于实现堆栈和队列非常有用。链表中的每个节点都可以被推送或弹出,而不会影响大多数节点。在中间插入/删除节点也是如此。然而,在数组中,所有元素都必须移动,这在执行时间方面是一项昂贵的工作。

二叉树、二叉搜索树、哈希表和try是其中的一些数据结构——至少在C语言中——你需要链表作为构建它们的基本成分。

但是,在期望链表能够通过其索引调用任何任意元素的情况下,应该避免使用链表。

其他回答

在以下情况下,链表比数组更可取:

您需要从列表中进行固定时间的插入/删除(例如在实时计算中,时间可预测性是绝对关键的) 你不知道列表中会有多少项。对于数组,如果数组变得太大,可能需要重新声明和复制内存 你不需要随机访问任何元素 您希望能够在列表中间插入项(例如优先级队列)

数组在以下情况下更可取:

you need indexed/random access to elements you know the number of elements in the array ahead of time so that you can allocate the correct amount of memory for the array you need speed when iterating through all the elements in sequence. You can use pointer math on the array to access each element, whereas you need to lookup the node based on the pointer for each element in linked list, which may result in page faults which may result in performance hits. memory is a concern. Filled arrays take up less memory than linked lists. Each element in the array is just the data. Each linked list node requires the data as well as one (or more) pointers to the other elements in the linked list.

数组列表(就像。net中的那些)给你数组的好处,但动态地为你分配资源,所以你不需要太担心列表的大小,你可以删除任何索引上的项目,而不需要任何努力或重新排列元素。在性能方面,数组列表比原始数组慢。

Algorithm           ArrayList   LinkedList
seek front            O(1)         O(1)
seek back             O(1)         O(1)
seek to index         O(1)         O(N)
insert at front       O(N)         O(1)
insert at back        O(1)         O(1)
insert after an item  O(N)         O(1)

数组列表适用于写一次读多次或追加程序,但不适用于从前面或中间进行添加/删除。

To add to the other answers, most array list implementations reserve extra capacity at the end of the list so that new elements can be added to the end of the list in O(1) time. When the capacity of an array list is exceeded, a new, larger array is allocated internally, and all the old elements are copied over. Usually, the new array is double the size of the old one. This means that on average, adding new elements to the end of an array list is an O(1) operation in these implementations. So even if you don't know the number of elements in advance, an array list may still be faster than a linked list for adding elements, as long as you are adding them at the end. Obviously, inserting new elements at arbitrary locations in an array list is still an O(n) operation.

访问数组列表中的元素也比访问链表快,即使访问是顺序的。这是因为数组元素存储在连续的内存中,可以很容易地缓存。链表节点可能分散在许多不同的页面上。

如果知道要在任意位置插入或删除项,我建议只使用链表。数组列表在其他方面会更快。

这完全取决于你在迭代时所做的操作类型,所有数据结构都在时间和内存之间进行权衡,我们应该根据需要选择正确的DS。有些情况下,LinkedList比数组快,反之亦然。考虑数据结构上的三个基本操作。

搜索

由于array是基于索引的数据结构,搜索array.get(index)将花费O(1)时间,而linkedlist不是索引DS,因此您将需要遍历到index,其中index <=n, n是链表的大小,因此array在随机访问元素时比链表更快。

那么,这背后有什么好处呢?

As Arrays are contiguous memory blocks, large chunks of them will be loaded into the cache upon first access this makes it comparatively quick to access remaining elements of the array,as much as we access the elements in array locality of reference also increases thus less catch misses, Cache locality refers to the operations being in the cache and thus execute much faster as compared to in memory,basically In array we maximize the chances of sequential element access being in the cache. While Linked lists aren't necessarily in contiguous blocks of memory, there's no guarantee that items which appear sequentially in the list are actually arranged near each-other in memory, this means fewer cache hits e.g. more cache misses because we need to read from memory for every access of linked list element which increases the time it takes to access them and degraded performance so if we are doing more random access operation aka searching , array will be fast as explained below.

插入

这是简单和快速的LinkedList的插入是O(1)操作在LinkedList (Java)阵列相比,考虑数组充满的情况下,我们需要将内容复制到新数组如果数组完全使一个元素插入ArrayList O (n)在坏的情况下,而ArrayList还需要更新其指数年底如果你插入一些除了数组,链表的我们不必调整它,你只需要更新指针。

删除

它的工作原理类似于插入,在LinkedList中比在array中更好。

我认为主要的区别在于你是否经常需要从列表顶部插入或删除内容。

对于一个数组,如果你从列表的顶部移除一些东西复杂度是o(n)因为数组元素的所有下标都要移位。

对于链表,它是o(1),因为您只需要创建节点,重新分配头,并将对next的引用分配为前一个头。

当经常在列表的末尾插入或删除时,数组是更可取的,因为复杂度将是o(1),不需要重新索引,但对于链表,它将是o(n),因为你需要从头到最后一个节点。

我认为在链表和数组中搜索都是o(log n)因为你可能会使用二分搜索。