答案 1:
在开始时存储 K 个堆栈指针。现在将之后的第一个地址标记为地址 0(让生活更简单)
一个偶数 K 堆栈 (stack_0, stack_2, ...) 应该向上增长;奇数 K 堆栈 (stack_1, ..) 应该向下增长
在将数组初始化为 K/2 部分时(为了简单起见,假设 K 是偶数)。
stack0 从地址 0 开始
stack1 从 (arraySize / (k/2)) 开始向下增长
stack3 从 (arraySize / (k/2)) 开始向上增长
当将数据压入某个堆栈时,我们应该确保它不会溢出到相邻的堆栈,否则会抛出异常。
数组应如下所示:
[[stack pointers][stack_0][stack_1]...[stack_k]] 其中 stack[0] 和 stack[1] 都共享相同的区域,因此它们可以最佳地利用可用的空间。
可以通过将每个大堆栈与一个小堆栈配对来进行进一步的优化(这可以通过检查堆栈随时间的行为来完成)。此外,将快速变化的数组与缓慢变化的数组组合在一起可能会有所帮助。
答案 2:
对此进行了更多思考,我看到我的第一个解决方案只保证使用 array_size/(k/2) (因为如果我们只有一个大小为 array_size/(k/2) 的数组,我们将得到堆栈溢出)。
以下(完全不切实际的)解决方案可以满足要求:
我们为我们的 k 个堆栈指针分配数组的开头,并从现在开始忽略该区域。
在数组的其余部分,我们将每个单元格视为一个结构 [data, previous, next]。
push(stack_i, data) -> 从堆栈指针区域获取 sp_i。然后转到该地址,填写“next”指针以指向数组中的下一个空单元格(我们可以将所有空白空间链接到另一个堆栈中,因此这是 o(1))。在“下一个”单元格中存储我们的数据,并填写“上一个”指针。更新 sp_i
pop(stack_i) -> 获取 sp_i。从该单元格中获取“数据”。该单元格中的“prev”是我们的新 sp_i。将旧的(现在为空的)单元格推送到空列表中。