为什么有人想要使用链表而不是数组?

毫无疑问,编码一个链表比使用数组要多一些工作,人们可能会想知道如何才能证明这些额外的工作是合理的。

我认为在链表中插入新元素是微不足道的,但在数组中这是一个主要的任务。与将数据存储在数组中相比,使用链表存储一组数据还有其他优点吗?

这个问题不是这个问题的重复,因为另一个问题是专门问一个特定的Java类,而这个问题是关于一般数据结构的。


当前回答

Arrays make sense where the exact number of items will be known, and where searching by index makes sense. For example, if I wanted to store the exact state of my video output at a given moment without compression I would probably use an array of size [1024][768]. This will provide me with exactly what I need, and a list would be much, much slower to get the value of a given pixel. In places where an array does not make sense there are generally better data types than a list to deal with data effectively.

其他回答

维基百科上有很好的章节介绍了它们的区别。

Linked lists have several advantages over arrays. Elements can be inserted into linked lists indefinitely, while an array will eventually either fill up or need to be resized, an expensive operation that may not even be possible if memory is fragmented. Similarly, an array from which many elements are removed may become wastefully empty or need to be made smaller. On the other hand, arrays allow random access, while linked lists allow only sequential access to elements. Singly-linked lists, in fact, can only be traversed in one direction. This makes linked lists unsuitable for applications where it's useful to look up an element by its index quickly, such as heapsort. Sequential access on arrays is also faster than on linked lists on many machines due to locality of reference and data caches. Linked lists receive almost no benefit from the cache. Another disadvantage of linked lists is the extra storage needed for references, which often makes them impractical for lists of small data items such as characters or boolean values. It can also be slow, and with a naïve allocator, wasteful, to allocate memory separately for each new element, a problem generally solved using memory pools.

http://en.wikipedia.org/wiki/Linked_list

链表比数组的维护开销更大,它还需要额外的内存存储,所有这些都是一致的。但是有一些事情是数组做不到的。在很多情况下,假设你想要一个长度为10^9的数组你无法得到它,因为必须有一个连续的内存位置。链表可能是这里的救世主。

假设你想用数据存储多个东西,那么它们可以很容易地扩展到链表中。

STL容器通常在后台有链表实现。

根据你的语言,可以考虑以下一些缺点和优点:

C编程语言:当使用链表(通常是通过结构指针)时,必须特别注意不要泄漏内存。正如前面提到的,链表很容易洗牌,因为我们所做的只是改变指针,但是我们会记得释放所有的东西吗?

Java: Java具有自动垃圾收集功能,因此内存泄漏不会成为问题,但是对于高级程序员来说,隐藏了链表的实现细节。从列表中间删除节点等方法的过程比该语言的一些用户所期望的要复杂得多。

链表是一个动态的数据结构,因此它可以在运行时通过分配和释放内存来增长和收缩。所以不需要给出链表的初始大小。插入和删除节点非常容易。

2-链表的大小可以在运行时增加或减少,因此没有内存浪费。在数组的情况下,有很多内存浪费,比如如果我们声明一个大小为10的数组,只存储6个元素,那么4个元素的空间就浪费了。链表中不存在这样的问题,因为只有在需要时才分配内存。

3-数据结构,如堆栈和队列可以很容易地实现使用链表。

链表

它更可取的时候,它涉及到插入!基本上它所做的就是处理指针

1 -> 3 -> 4

插入(2)

1... 3... 4 ... 2

最后

1 -> 2 -> 3 -> 4

一个箭头指向3点,另一个箭头指向2点

简单!

但是来自Array

| | 1 | 3 | 4

插入(2) | 1 | 3 | | 4 | | 1 | | 3 | 4 | | 1 | 2 | 3 | 4 |

任何人都可以想象出其中的不同! 对于4个索引,我们执行3个步骤

如果数组长度是一百万呢?数组有效吗? 答案是否定的!:)

删除也是一样! 在链表中,我们可以简单地使用指针并将对象类中的元素和next置空! 但对于数组,我们需要执行shiftLeft()

希望有帮助!:)