我有点困惑。列表擅长插入任何位置,但不善于随机访问?
(怎么可能)如果你不能做随机访问,你怎么知道在哪里插入?
同样,如果您可以在任何位置插入,为什么不能有效地从该位置读取?
答案 0 :(得分:4)
如果您已经有要插入的列表节点,则插入只需要分配列表节点并调整几个指针。当然,如果您只知道要插入的索引,则缺少随机访问意味着您需要O(n)时间到达该节点,即使您只需要O(1 )到达那里后需要额外的时间插入。
答案 1 :(得分:1)
我有点困惑。列表擅长插入任何位置, 但不善于随意访问?
真。但它(List)在访问该位置后插入任何位置。 访问顺序为O(n),插入顺序为O(1)。
如果你不能随机访问,你怎么知道在哪里插入?
它只是插入特定的位置,开头,结尾或迭代器指示的位置。
如果您可以插入任何位置,为什么不能有效地阅读 那个位置?
它可以在顺序访问后插入任何位置。
答案 2 :(得分:1)
如果您必须寻找它,列表不适合插入任何位置。它们可以快速将事物放在前面(如果你缓存它就结束),并且在中间给出一个已经找到的迭代器,插入速度很快。所以,你不会感到困惑,你只是误解了你被告知的事情。
答案 3 :(得分:1)
关联列表
列表使用指向元素的指针进行操作 - 它们在内存中可能是不连续的(不按顺序)。
所以,例如单链表将包含指针:
head -> element1 -> element2 -> element3 -> NULL
^ cur ptr
每个元素都可以定义为结构:
struct Element {
Element *next;
int data;
};
* next指针指向列表中的下一个元素。
因此,要将列表遍历到例如,最后一个元素,您将需要执行以下操作:
while (*curNode->next != NULL) {
*curNode = curNode->next;
}
// curNode after traversing would be last node
curNode->data; // get data in last node
遍历后指向最后一个元素的指针如下所示:
head -> element1 -> element2 -> element3 -> NULL
^ cur ptr (3 hops)
因此你需要做n跳才能到达最后一个节点(除非你有一个指向最后一个元素的指针,也就是一个“尾”指针。)
要插入某个位置,您需要遍历该元素,直到找到正确的插槽。在所描述的单链表中,它将是O(n)。
您可以使用其他类型的列表来改善列表的遍历时间,例如:根据您的需要,双重链表等。但要注意,连接这些列表可能会更复杂。
VS阵列/ STL载体:
数据在内存中是连续的。因此,要访问它,您只需获取第一个元素+索引的地址进行迭代,然后取消引用该位置。因此,您可以随机进行即时访问。在这种情况下,复杂性因此是O(1)。