Python中的高效堆栈实现
Posted
技术标签:
【中文标题】Python中的高效堆栈实现【英文标题】:Efficient Stack implementation in Python 【发布时间】:2015-09-22 15:53:34 【问题描述】:第一次实现:以下堆栈实现假定列表的末尾将包含堆栈的顶部元素。随着堆栈的增长,新项目将被添加到列表的末尾。
class Stack:
def __init__(self):
self.items = []
def isEmpty(self):
return self.items == []
def push(self, item):
self.items.append(item)
def pop(self):
return self.items.pop()
def peek(self):
return self.items[len(self.items)-1]
def size(self):
return len(self.items)
第二个实现:第二个实现假设列表的开头包含堆栈的顶部元素,并且在索引 0 处添加新项目。
class Stack:
def __init__(self):
self.items = []
def isEmpty(self):
return self.items == []
def push(self, item):
self.items.insert(0,item)
def pop(self):
return self.items.pop(0)
def peek(self):
return self.items[0]
def size(self):
return len(self.items)
作为数据结构的初学者,我想知道:
1. 哪种实现在时间或空间方面更有效,为什么?
2. 是第二次实现中insert(0)
的时间复杂度 O(n)。如果是,如何?
【问题讨论】:
见wiki.python.org/moin/TimeComplexity。请注意,self.items[-1]
会为您提供最后一个元素较少的问题。
是的,先重写你的peek
方法。并称之为 tos,也许(栈顶)
感谢@jonrsharpe 提供链接。
【参考方案1】:
列表已针对从末尾追加和弹出进行了优化。从列表的开头插入或删除项目的成本要高得多,因为所有项目都需要移动。
Python 确实有一个数据结构 collections.deque
,它针对在两端追加进行了优化。
【讨论】:
【参考方案2】:在 Python 中,列表是通过可调整大小的对其他对象的引用数组来实现的。
见How are lists implemented?
因此,在列表末尾推送/弹出元素将比在列表开头推送/弹出更有效。
在数组的开头添加/删除元素非常昂贵,因为您必须将所有其他元素移动到一个空格上。另一方面,假设数组末尾有足够的空白空间,在数组末尾添加/删除元素相对便宜。
当数组已满时,Python 会动态地为该数组的末尾分配更多内存,虽然代价高昂,但摊销后的性能仍然非常出色。
【讨论】:
【参考方案3】:def __init__(self):
self.items=[]
def push(self,item):
self.items.append(item)
def pop(self):
return self.items.pop()
def isEmpty(self):
return self.items==[]
def peek(self):
return self.items[len(self.items)-1]
def size(self):
return len(self.items)
`
【讨论】:
以上是关于Python中的高效堆栈实现的主要内容,如果未能解决你的问题,请参考以下文章