用数组实现3个栈之固定分割(Java)

  摘自《程序员面试金典》

我们首先最容易想到的就是固定分割的方法:将数组等分为3分,每一份均可以被看做一个栈,然后可以在每个栈上执行出入栈的操作。

这种方法优点是比较直接,实现简单。当然缺点是不够灵活,有可能一个栈出现了空间溢出的情况,而其他栈还是空的状态。

  下面说下实现的思路,首先对于长度为n的数组,我们的划分标准如下(假设数组下标从0开始):

  1)栈1,使用[0, n/3)

  1)栈2,使用[n/3, 2n/3)

  1)栈3,使用[2n/3, n)

为了控制每个栈在数组中的活动范围,我们设置常量stackSize表示每个栈的大小,并设置3个常数(stackPointer,使用stackTop命名是不合适的)来记录栈顶的位置,

假设n = 300的话,那么stackSize = 100,而每个stackPointer元素的取值范围为-1 ~ 99(其中-1表示栈为空,0~99表示栈的有效区间)。由于进行

出栈入栈的操作是在一个数组上,所以我们必须能够得到不同的栈的栈顶在数组中位置。假设我们以stackNum(stackNum = 0,1,2)表示将对哪个栈

进行操作,则第stackNum个栈的栈顶位置应该为stackSize * stackNum + stackPointer[stackNum]。由于需要经常使用这个操作,我们将它放到一个独立

的方法topOfStack中去。代码中buffer表示数组。

int stackSize = 100;
int[] stackPointer = {-1, -1, -1};
int[] buffer = new int[stackSize * 3];
/*返回栈“stackNum"栈顶元素,在数组中的索引*/
int topOfStack(int stackNum){
     return stackSize * stackNum + stackPointer[stackNum];  
}

  接下来是对栈的操作,我们这里提供出入栈,取栈顶元素的实现(这里假设数组为整数数组)。

  1)入栈操作,输入为入栈的元素和带操作的栈序号

void push(int stackNum, int value){
    if(stackPointer[stackNum] + 1 >= stackSize)
          return;  
    //栈顶指针自增,然后更新栈顶元素
    stackPointer[stackNum]++;
    buffer[topOfStack(stackNum)] = value;
}

  2)出栈操作

int pop(int stackNum) throws Exception{
     if(stackPointer[stackNum] == -1)
         throw new Exception("栈为空,无法出栈");
     //获取栈顶的元素,并将栈顶位置清零,同时指针自减
     int value = buffer[topOfStack(stackNum)];
     buffer[topOfStack(stackNum)] = 0;
     stackPointer[stackNum] --;
     return value;
}

  3)获得栈顶元素

int top(int stackNum) throws Exception{
     if(stackPointer[stackNum] == -1)
         throw new Exception("栈为空,无法获得栈顶元素");
     return buffer[topOfStack(stackNum)];
}

完整代码如下所示:

public class StackByArray {
    int stackSize = 100;
    int[] stackPointer = {-1, -1, -1};
    int[] buffer = new int[stackSize * 3];
    
    void push(int stackNum, int value){
        if(stackPointer[stackNum] + 1 >= stackSize)
              return;  
        //栈顶指针自增,然后更新栈顶元素
        stackPointer[stackNum]++;
        buffer[topOfStack(stackNum)] = value;
    }
    
    int pop(int stackNum) throws Exception{
         if(stackPointer[stackNum] == -1)
             throw new Exception("栈为空,无法出栈");
         //获取栈顶的元素,并将栈顶位置清零,同时指针自减
         int value = buffer[topOfStack(stackNum)];
         buffer[topOfStack(stackNum)] = 0;
         stackPointer[stackNum] --;
         return value;
    }
    
    int top(int stackNum) throws Exception{
         if(stackPointer[stackNum] == -1)
             throw new Exception("栈为空,无法获得栈顶元素");
         return buffer[topOfStack(stackNum)];
    }
    
    /*返回栈“stackNum"栈顶元素,在数组中的索引*/
    int topOfStack(int stackNum){
         return stackSize * stackNum + stackPointer[stackNum];  
    }
    public static void main(String[] args) {
        StackByArray stack = new StackByArray();
        stack.push(0, 1);
        stack.push(0, 2);
        stack.push(1, 3);
        stack.push(1, 4);
        stack.push(2, 11);
        
        try {
            System.out.println(stack.top(2));
            stack.pop(2);
            stack.top(2);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
View Code

转载于:https://www.cnblogs.com/liujinyao/p/4685225.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值