为什么有人想要使用链表而不是数组?
毫无疑问,编码一个链表比使用数组要多一些工作,人们可能会想知道如何才能证明这些额外的工作是合理的。
我认为在链表中插入新元素是微不足道的,但在数组中这是一个主要的任务。与将数据存储在数组中相比,使用链表存储一组数据还有其他优点吗?
这个问题不是这个问题的重复,因为另一个问题是专门问一个特定的Java类,而这个问题是关于一般数据结构的。
为什么有人想要使用链表而不是数组?
毫无疑问,编码一个链表比使用数组要多一些工作,人们可能会想知道如何才能证明这些额外的工作是合理的。
我认为在链表中插入新元素是微不足道的,但在数组中这是一个主要的任务。与将数据存储在数组中相比,使用链表存储一组数据还有其他优点吗?
这个问题不是这个问题的重复,因为另一个问题是专门问一个特定的Java类,而这个问题是关于一般数据结构的。
当前回答
快速插入和删除确实是链表的最佳参数。如果您的结构是动态增长的,并且不需要对任何元素进行固定时间的访问(例如动态堆栈和队列),链表是一个很好的选择。
其他回答
链表
它更可取的时候,它涉及到插入!基本上它所做的就是处理指针
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()
希望有帮助!:)
假设您有一个有序集,您还想通过添加和删除元素来修改它。此外,您需要能够以这样的方式保留对元素的引用,以便稍后可以获得前一个或下一个元素。例如,一本书中的待办事项列表或一组段落。
首先,我们应该注意到,如果您想在集合本身之外保留对对象的引用,那么您可能最终会将指针存储在数组中,而不是存储对象本身。否则你将无法插入到数组中-如果对象嵌入到数组中,它们将在插入期间移动,并且任何指向它们的指针都将无效。数组下标也是如此。
您的第一个问题,正如您自己所注意到的,是插入链表允许插入O(1),但数组通常需要O(n)。这个问题可以部分克服——可以创建一种数据结构,提供类似数组的按顺序访问接口,其中读和写在最坏的情况下都是对数的。
Your second, and more severe problem is that given an element finding next element is O(n). If the set was not modified you could retain the index of the element as the reference instead of the pointer thus making find-next an O(1) operation, but as it is all you have is a pointer to the object itself and no way to determine its current index in the array other than by scanning the entire "array". This is an insurmountable problem for arrays - even if you can optimized insertions, there is nothing you can do to optimize find-next type operation.
另一个很好的原因是链表非常适合高效的多线程实现。这样做的原因是,更改往往是局部的——只影响数据结构局部部分的插入和删除的一两个指针。所以,你可以让多个线程在同一个链表上工作。更重要的是,可以使用cas类型的操作创建无锁版本,并完全避免沉重的锁。
使用链表,迭代器还可以在进行修改时遍历列表。在修改没有冲突的乐观情况下,迭代器可以在没有争用的情况下继续。
对于数组,任何修改数组大小的更改都可能需要锁定数组的很大一部分,事实上,这是在整个数组上没有全局锁的情况下完成的,因此修改会停止全局事务。
这实际上是一个效率问题,在链表中插入、删除或移动(而不是简单地交换)元素的开销是最小的,即操作本身是O(1),而不是O(n)。如果您大量操作数据列表,这可能会产生显著的差异。您可以根据对数据类型的操作方式选择数据类型,并为所使用的算法选择最有效的数据类型。
首先,在c++中,使用链表应该不会比使用数组更麻烦。对于链表,可以使用std::list或boost指针列表。链表与数组的关键问题是指针需要额外的空间和糟糕的随机访问。你应该使用链表,如果你
你不需要随机访问数据 您将添加/删除元素,特别是列表中间的元素