【问题标题】:Time complexity of a Stack ADT implemented using a Linked List使用链表实现的堆栈 ADT 的时间复杂度
【发布时间】:2011-06-30 15:22:20
【问题描述】:
对于使用 LinkedList 实现的 Stack 抽象数据类型,put(x) 和 get() 函数的时间复杂度是多少?
我的第一个想法是它们都是 O(1)。但是如果 get() 必须从头节点遍历到列表中的最后一个元素才能找到要删除并返回的元素,那么 get() 函数将是 O(n)。
put(x) 函数也必须遍历整个列表以找到最后一个节点,它将在其中安装一个新节点。所以这也是 O(n)。
如果使用 LinkedList 的“特殊”版本,即始终保留指向列表中最后一个节点的指针,则这些都将成为常量时间操作。我是否正确理解 LinkedList 的标准实现不会提供此功能?
【问题讨论】:
标签:
pointers
data-structures
stack
time-complexity
abstract-data-type
【解决方案1】:
您不必在列表末尾插入。如果在(单链)列表的前面插入,它们都是O(1)。
堆栈包含 1,2,3:
[1]->[2]->[3]
按 5:
[5]->[1]->[2]->[3]
流行:
[1]->[2]->[3], returning 5
【解决方案2】:
对于双向链表,堆栈操作 push 和 pop 都应该是 O(1)。
如果你被单链表困住,假设你对保持指向尾部和头部的指针的持续开销没问题,你可以有 O(1) 的入队和出队队列操作。而且因为通过摊销恒定开销,您可以将两个队列组成一个堆栈,最终,您可以实现 O(1) 的推送和弹出。
【解决方案3】:
栈的基本功能是push和pop操作都是从栈顶执行的,即链表的头部。当实现链表时,会维护一个指向列表中第一个元素的头指针,因此用于从堆栈中添加/删除元素的 put(x) 和 get() 操作将始终为 O(1)。