为了获得最大效率,这可能是实现循环缓冲区的自定义类。
只需在实例化时创建一个固定大小的数组来保存数据。此外还有一个起始索引、一个大小成员和一个容量,这样您就可以知道缓冲区中有多少数据以及它从哪里开始。
因此,首先,您的列表不包含数据,起始位置为 0,大小为 0。
当你添加一个项目时,它会进入元素(start + size) % capacity
,size
如果它还不是 at 则递增capacity
。如果它是at capacity
,你start
也会增加,如果需要的话环绕:start = (start + 1) % capacity
。
要从列表中获取索引处的元素n
,您实际上可以使用以下命令对其进行调整start
:
return element[(start + n) % capacity];
我没有涉及删除列表的开头,因为那不在您的规范中。但是,这是一个简单的检查,以确保size
不是 0,然后在 处提取项目,然后使用上面显示的相同环绕element[start]
递增。start
在伪代码中(未经测试但应该接近):
def listNew (capacity):
me = new object
me.capacity = capacity
me.data = new array[capacity]
me.start = 0
me.size = 0
return me
def listAdd (me, item):
if me.size = me.capacity:
me.data[me.start] = item
me.start = (me.start + 1) % me.capacity
else:
me.data[(me.start + me.size) % me.capacity] = item
me.size = me.size + 1
def listGet (me, index):
if index > size:
return 0 # or raise error of some sort
return me.data[(me.start + index) % me.capacity]
def listRemove (me):
if size == 0:
return 0 # or raise error of some sort
item = me.data[(me.start + index) % me.capacity]
me.start = (me.start + 1) % me.capacity
me.size = me.size - 1
return item
根据要求,所有这些操作都是 O(1) 时间复杂度。
对于将数字添加到五元素列表的特定示例1
,8
您最终会得到:
0 1 2 3 4 <--- index
+---+---+---+---+---+
| 6 | 7 | 8 | 4 | 5 |
+---+---+---+---+---+
^
+--------- start = 3
size = 5
capacity = 5
这样,从缓冲区中提取虚拟索引 3(第四个数字)将为您提供一个实际索引:
(start + 3) % capacity
= ( 3 + 3) % 5
= 6 % 5
= 1