位置列表 ADT 的需求在哪里?

Where is the need for the positional list ADT?

在哪里可以使用(双向链表)位置列表 ADT?当开发人员想要 O(n) 内存和 O(1)(非摊销行为)到列表中的任意位置时?我想看一个使用位置列表的例子。使用位置列表比使用基于数组的序列有什么优势?

如果您的程序经常需要向数据集合中添加新元素或从中删除元素,那么列表可能是比数组更好的选择。

删除数组第N个元素需要对第N个元素之后的所有元素进行复制操作,原则上:

Arr[N] = Arr[N+1]
Arr[N+1] = Arr[N+2]
...

插入新元素时需要类似的副本,即为新元素腾出空间。

如果您的程序频繁使用 adds/deletes 元素,那么多次复制操作可能会影响性能。

作为这些操作的一部分,现有元素的位置会发生变化,即在位置 50 的元素 deleted/added 之后,位置 1000 的元素将位于位置 999 或 1001。

如果您的程序的某些部分搜索了特定元素并保存了它的位置(例如位置 1000),这可能会成为问题。元素delete/add操作后,保存的位置不再有效。

一个(双向链接)列表“解决”了所描述的 3 个问题。使用列表,您可以 add/delete 个元素,而无需将现有元素复制到新位置。因此,特定元素的位置(例如指向元素的指针)在 add/delete 操作后仍然有效。

总结一下:如果您的程序(经常)添加或删除随机定位的元素,并且如果您的程序要求位置信息不受 add/delete 操作的影响,则列表可能是比数组更好的选择.

位置列表

  • 因此,在处理数组时,索引在定位插入和删除位置方面非常有用。然而,索引对于链接结构(如链表)来说并不是很好,主要是因为即使我们有索引。我们仍然需要遍历 liked 结构中的所有先前节点。这意味着在链表中基于索引的删除或插入将 运行 O(N) 时间(没有布埃诺)。一般的经验法则是,对于数据结构操作,我们希望它们 运行 O(1)O(log n)。此外,索引不擅长描述相对于其他节点的位置。

职位允许我们做什么?

  • 位置允许我们在我们喜欢的结构中的任意位置实现恒定时间插入和删除(很酷,对吧??)。
  • 它们还允许我们相对于其他元素来描述元素。
  • 本质上,Position 为我们提供了一个内存地址的引用,然后我们可以将其用于恒定时间的插入和删除。您的教科书图像没有显示验证方法,但是,我认为实现确实如此。所以请注意,您将需要一个实用方法 validate 来验证该位置是否在链接结构中。

职位是什么样的?

  • 实际上,Position 是 ADT(抽象数据类型),在 Java 中,我们使用接口形式化 ADT,如下所示:
public interface Position <E>{

    E getElement()throws IllegalStateException;
}
  • Position 只是在链接结构中的 Node 上实现的抽象。为什么要这样做?好吧,它为我们的代码提供了更大的灵活性和更好的抽象。
  • 所以要为链表节点实现一个位置,它看起来像这样:

private static class Node<E> implements Position<E> {
// ALL THE OTHER METHODS WOULD BE HERE
}

  • 节点 class 是私有和静态的,因为假定它嵌套在链表 class 中。然后最终我们在处理 Positional Linked list 中的所有其他方法时使用此 Position 作为数据类型。

现实世界的例子

  • 您可以使用此方法为解析器创建 parse tree。您可以拥有一棵二叉树,它为其所有方法实现和使用 Position 接口,然后使用该树进行解析