zoukankan      html  css  js  c++  java
  • 在一个数组里面实现三个栈

    * 使用一个数组来实现三个栈:
    * 这个问题是数组实现一个栈的升级版本,
    * 一个数组实现两个栈比较的简单,可以从数组的两端到中间,也可以从中间到两端,以至于实现三个四个五个栈都行,关键是要记住栈的开始处,当栈的容量不够时做好调整
    * 就单单对这个问题而言,一个数组实现三个栈又有一下两种处理方式:
    * 1、把数组均分成三部分 [0, n/3) [n/3, 2n/3) [2n/3, n-1)
    * 这种做法有个弊端,就是三个栈的大小都是固定的,有时某个栈实际使用的空间可能很小,而有的栈的空间却又不够用,于是造成了很大的浪费,有一种可以考虑的做法就是事先预估
    * 这三个栈各自可能的大小,按需分配空间大小。实践中更有意义的做法是使用下面弹性大小的方法
    * 2、所谓弹性大小的方法,就是记录各个栈的初试位置,然后就可以快乐的使用栈了,当某个栈的空间不够时就移动栈。
    * 这种想法来实现三个栈时,恰恰又有一个小诀窍之处:数组的两端作为两个栈的base,第三个栈同时标记栈顶和栈顶,数组头和数组尾栈均向数组中间长,中间的数组向数组
    * 低地址长,任何一个数组push操作空间不够时 就需要 shift中间的栈
    * 还有就是注意,中间的栈左右移动的距离每次是1,本来想设计的 是可以自己随意修改这个移动的步长,但是发现这样没有实际意义,还是不如每次移动一个步长

      1 ublic class Arr3Stack {
      2     public static void main(String[] args) {
      3         ThreeStackUsingOneArray<Integer> arr = new ThreeStackUsingOneArray<Integer>();
      4         
      5         System.out.println("array is full : "+arr.isFull());
      6         
      7         arr.push(0,1);
      8         arr.push(1, 3);
      9         arr.push(1, 2);
     10         arr.push(2, 5);
     11         arr.push(2, 4);
     12         
     13         System.out.println("array is full : "+arr.isFull());
     14         
     15         arr.print();
     16     }
     17 }
     18 
     19 class ThreeStackUsingOneArray <AnyType>{
     20     private AnyType[] array = null;
     21     private int arrayLength = 5;    //定义数组的初试长度
     22     
     23     // 以为 stack2 stack3的栈底是 数组的首和尾所以 定义这两个站的 栈顶
     24     int stackOneTop;    // stack 1的栈顶
     25     int stackTwoTop;    // stack 2 的栈顶
     26     int stackTwoBase;    //stack 2的
     27     int stackThreeTop;    //stack 3的栈顶
     28     /*
     29      * 中间栈需要移动的方向
     30      * 0 不用搬动,Array is full
     31      * 1 向后移动
     32      * -1 向前移动
     33      */
     34     int flag = -2;
     35     
     36     public ThreeStackUsingOneArray()
     37     {
     38         init();
     39     }
     40     public ThreeStackUsingOneArray(int len)
     41     {
     42         arrayLength = len;
     43         init();
     44     }
     45     
     46     public void init()
     47     {
     48         array = (AnyType[]) new Object[arrayLength];    //应对创建 泛型数组的问题
     49         
     50         stackOneTop = 0;
     51         stackThreeTop = arrayLength - 1;
     52         stackTwoBase = (arrayLength-1) * 2 / 3;
     53         stackTwoTop = stackTwoBase;
     54         
     55     }
     56     
     57     //print the array
     58     public void print()
     59     {
     60         for (int i = 0; i < array.length; i ++)
     61         {
     62             System.out.println(array[i]);
     63         }
     64     }
     65 
     66     // 判断当前数组是不是full
     67     public boolean isFull()
     68     {
     69         if(stackOneTop > stackTwoTop && stackTwoBase >= stackThreeTop)
     70             return true;
     71         return false;
     72     }
     73     
     74     /**
     75      * 后面的栈的操作 一律都带有一个栈的标号 stackNum = 0 , 1, 2, 表示堆第stacjNum进行操作
     76      */
     77     public void push(int stackNum, AnyType x)
     78     {
     79         if(isFull())
     80             throw new RuntimeException(new Exception("array is full"));
     81         
     82         
     83         if(stackNum == 0)
     84         {
     85             if(flag == 1)    // 需要把中间的一个栈 往后面移动
     86                 shiftStackTwo();
     87             
     88             array[stackOneTop ++] = x;
     89             
     90         }else if(stackNum == 1){
     91             if(flag == 1)
     92                 shiftStackTwo();
     93             
     94             array[stackTwoTop --] = x;
     95             
     96         }else if(stackNum == 2){
     97             if(flag == -1)
     98                 shiftStackTwo();
     99             array[stackThreeTop --] = x;
    100             
    101         }else
    102             throw new RuntimeException(new Exception("stackNum is out"));
    103     
    104         if(isFull())
    105             flag = 0;    //array os full
    106         if(stackOneTop > stackTwoTop)
    107         {
    108             flag = 1;    //中间的栈 往后面移动
    109         }
    110         if (stackTwoBase == stackThreeTop)
    111         {
    112             flag = -1;    //中间的栈 往前面移动
    113         }
    114     }
    115 
    116     public void shiftStackTwo() {
    117         switch(flag)
    118         {
    119             case 0:
    120                 throw new RuntimeException(new Exception("array is full"));
    121             case 1:    //中间的栈 向后移动 step
    122                 // 检查 还有没有可以往后移动的空间
    123                 if(stackTwoBase+1 > stackThreeTop)
    124                     throw new RuntimeException(new Exception("array is full"));
    125                 for( int i = stackTwoBase; i >= stackTwoTop-1; i --)
    126                     array[i+1] = array[i];
    127                 stackTwoTop ++; stackTwoBase ++;
    128                 break;
    129             case -1:
    130                 // 检查前面还有没空间
    131                 if(stackOneTop-1 > stackTwoTop)
    132                     throw new RuntimeException(new Exception("array is full"));
    133                 for(int i = stackTwoTop-1; i <= stackTwoBase; i++)
    134                     array[i-1] = array[i];
    135                 stackTwoTop --; stackTwoBase --;
    136                 break;
    137             default:
    138                 break;
    139         }
    140     }
    141     
    142     public boolean isEmpty(int stackNum)
    143     {
    144         boolean b = false;
    145         switch (stackNum) {
    146         case 0:
    147             if(stackOneTop == 0) b = true;
    148             break;
    149             
    150         case 1:
    151             if(stackTwoTop == stackTwoBase) b = true;
    152             break;
    153 
    154         case 2:
    155             if(stackThreeTop == arrayLength-1) b = true;
    156             break;
    157             
    158         default:
    159             throw new RuntimeException(new Exception("stacknum is out"));
    160         }
    161         return b;
    162     }
    163     
    164     /*
    165      * 出站操作
    166      */
    167     public AnyType pop(int stackNum)
    168     {
    169         AnyType x ;
    170         switch (stackNum) {
    171         case 0:
    172             if(isEmpty(stackNum))
    173                 throw new RuntimeException(new Exception("stack"+stackNum+" is empty"));
    174             x = array[--stackOneTop];
    175             break;
    176         
    177         case 1:
    178             if(isEmpty(stackNum))
    179                 throw new RuntimeException(new Exception("stack"+stackNum+" is empty"));
    180             x = array[++stackTwoTop];
    181             break;
    182             
    183         case 2:
    184             if(isEmpty(stackNum))
    185                 throw new RuntimeException(new Exception("stack"+stackNum+" is empty"));
    186             x = array[++stackThreeTop];
    187             break;
    188             
    189         default:
    190             throw new RuntimeException(new Exception("stacknum is out"));
    191         }
    192         return x;
    193     }
    194     
    195 }
    View Code
  • 相关阅读:
    [Leetcode] 221. Maximal Square
    [翻译] TensorFlow Programmer's Guide之Frequently Asked Questions(问得频率最多的几个问题)
    [Kaggle] dogs-vs-cats之模型训练
    [Kaggle] dogs-vs-cats之建立模型
    [Kaggle] dogs-vs-cats之制作数据集[1]
    Linux虚拟机Centos 设置固定的静态IP
    linux IP动态变动之后 , 需要做的杂项操作
    GitBlit (1)-- 在linux 安装 GitBlit 并运行
    Linux 安装SVN
    微信开发(3) -- 支付后接收回调信息测试
  • 原文地址:https://www.cnblogs.com/OliverZhang/p/6641588.html
Copyright © 2011-2022 走看看