zoukankan      html  css  js  c++  java
  • 用数组实现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

  • 相关阅读:
    k-means聚类JAVA实例
    钓鱼站点以世界杯足球赛为饵,收集个人资料
    南桥--特殊回文数
    Oracle 数据文件管理
    hihoCoder #1142 : 三分求极值
    时间复杂度和空间复杂度[数据结构]
    poj 3635 Full Tank? ( 图上dp )
    FastQC结果详解
    毕业设计常见问题
    centos 查看USB接口的版本
  • 原文地址:https://www.cnblogs.com/liujinyao/p/4685225.html
Copyright © 2011-2022 走看看