题目
原文:
Describe how you could use a single array to implement three stacks.
译文:
描述怎样用一个单独的数组来实现三个栈。
解答
解法一:
将数组划分成3等份,每一份独立的用来实现堆栈。
*第一个堆栈:从 0 至 n/3
*第二个堆栈:从 n/3 至 2n/3
*第三个堆栈:从2n/3 至 n
这种解法是基于对每个堆栈的使用没有额外的使用说明,所以我们直接为每个堆栈划分固定的大小。
int stackSize=300;
int[] buffer=new int[stackSize*3];
int[] stackPointer={0,0,0};
void push(int stackNum,int value){
int index=stackNum*stackSize+stackPointer[stackNum]+1;
stackPointer[stackNum]++;
buffer[index]=value;
}
int pop(int stackNum){
int index=stackNum*stackSize+stackPointer[stackNum];
stackPointer[stackNum]--;
int value=buffer[index];
buffer[index]=0;
return value;
}
int peek(int stackNum){
int index=stackNum*stackSize+stackPointer[stackNum];
return buffer[index];
}
boolean isEmpty(int stackNum){
return stackPointer[stackNum]==stackNum*stackSize;
}
解法二:
解法二中的,主要数组中还有空余的空间,堆栈就还能增长。
每次为堆栈分配一个空间的时候,在这个新空间中记录上一个空间地址。这样堆栈中的每个元素都有一个指针指向之前的元素。
这样的实现方法有一个问题就是如果一个堆栈弹出一个空间(释放空间),这个空间并不会作为空闲空间现在数组后面。这样话我们就不能使用新产生的空闲空间。
为了解决这个问题,我们用一个列表来记录空闲的空间。当有新空闲空间出现,我们就把它加入到这个表中。如果需要新分配一个空间,就从这个表中删除一个元素。
这样的实现方法使得3个堆栈能够动态的使用数组的空间,但是这是以增大空间复杂度换来的。
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;
}
}
---EOF---