列表如何知道在哪里插入(有效)但无法进行随机访问?

时间:2013-04-13 13:07:33

标签: c++ list

我有点困惑。列表擅长插入任何位置,但不善于随机访问?

(怎么可能)如果你不能做随机访问,你怎么知道在哪里插入?

同样,如果您可以在任何位置插入,为什么不能有效地从该位置读取?

4 个答案:

答案 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)。