这是来自"破解编码面试": 问题:
答案: 在这种方法中,只要阵列中有任何空闲空间,任何堆栈都可以增长 我们按顺序为堆栈分配空间,并将新块链接到前一个块。这意味着堆栈中的任何新元素都会保留指向该特定堆栈的前一个顶层元素的指针 在这个实现中,我们面临一个未使用空间的问题例如,如果一个堆栈删除了它的一些元素,那么删除的元素可能不一定出现在ar-ray的末尾那么,在这种情况下,我们将无法使用那些新释放的空间 为了克服这个缺点,我们可以维护一个空闲列表,整个数组空间最初将被赋予空闲列表。对于每次插入,我们都会从空闲列表中删除一个条目。如果删除,我们只需添加索引免费单元格到自由列表 在这个实现中,我们将能够在可变空间利用方面具有灵活性,但我们需要增加空间复杂性。 答案代码:
{
int stackSize = 300;
int indexUsed = 0;
int[] stackPointer = {-1,-1,-1};
StackNode[] buffer = new StackNode[stackSize * 3];
void push(int stackNum, int value) {
int lastIndex = stackPointer[stackNum];
stackPointer[stackNum] = indexUsed;
indexUsed++;
buffer[stackPointer[stackNum]]=new StackNode(lastIndex,value);
}
int pop(int stackNum) {
int value = buffer[stackPointer[stackNum]].value;
int lastIndex = stackPointer[stackNum];
stackPointer[stackNum] = buffer[stackPointer[stackNum]].previous;
buffer[lastIndex] = null;
indexUsed--;
return value;
}
int peek(int stack) { return buffer[stackPointer[stack]].value; }
boolean isEmpty(int stackNum) { return stackPointer[stackNum] == -1; }
class StackNode {
public int previous;
public int value;
public StackNode(int p, int v){
value = v;
previous = p;
}
}
所以一开始我想说我来自C ++并且对不起,如果它是一些简单的java技巧或者我不了解java的东西,但无论如何都会学到新东西。 问题是,当我们尝试通过简单地链接数组中的堆栈元素以保持指向每个堆栈的前一个顶部el时解决它,然后我们将弹出一些元素,我们的数组将被分割,如果这些元素不是来自前面列表将无法检索那些释放的块或数组,即:
array: 1 2 3 2 4 6 4 8 12
stack no: 1 2 3 1 2 3 1 2 3
我们将从堆栈2弹出两次后,我们将得到:
array: 1 2 3 2 - 6 4 - 12
stack no: 1 2 3 1 2 3 1 2 3
所以我们放弃了对已删除块的引用,我们只能在"右边添加元素"阵列的一面。作者说,这可以通过上面提供的代码克服。但我无法理解如果他这么做的话 他分配了数组StackNode,然后通过将堆栈顶部设置为适当的前一个顶部(stackPointer)并弹出值为null然后减少数组中当前最大的元素来弹出每个元素?对我来说,它仍将片段数组,并另外跳过其他一些堆栈顶部元素。它可以工作的唯一合理方式是,如果我们的数组作为列表和赋值工作"缓冲区[lastIndex] = null"将从列表中删除该节点然后我们可以说我们在indexUsed中有一个元素少于数组 - 。