双端栈
定义:一个线性表的两端当做栈底分别进行入栈和出栈的操作,主要利用了栈"栈底位置不变,而栈顶位置动态变化"的特性。
我们把双端栈叫做ArrayDoubleEndStack,双端栈是线性表的一种,更是栈的一个特殊的分类,所以我们可以用动态数组和栈的思想来实现双端栈,毕竟由于其操作的特殊性,并不能借助ArrayList或者ArrayStack实现,所以这里需要从头开始实现双端栈
package 动态数组;
public class ArrayDoubleEndStack<E> {
private E[] data;//元素的容器
private int ltop;//左端栈的栈顶ltop=-1,左端栈为空ltop+1表示左端栈中元素的个数
private int rtop;//右端栈的栈顶rtop=data.length,右端栈为空length-rtop表示右端栈中元素的个数
private static int DEFAULT_SIZE=10;//双端栈的默认容量
public ArrayDoubleEndStack(){
data =(E[]) new Object[DEFAULT_SIZE];
//对两个标记进行赋值
rtop=data.length;
ltop=-1;
}
//入栈操作
public void push(E element,int stackId){
//如果栈满了,就需要扩容
if(ltop+1==rtop){
resize(data.length*2);
}
switch (stackId){
case 0://向左端栈入栈一个元素
data[++ltop]=element;
break;
case 1://向右端栈入栈一个元素
data[--rtop]=element;
break;
}
}
//出栈操作
public E pop(int stackId){
if(isEmpty(stackId)){
throw new NullPointerException("stack is null");
}
E ret =null;
switch(stackId){
case 0:
ret = data[ltop--];
break;
case 1:
ret = data[rtop++];
break;
}
//如果元素个数<=len/4 && len>DEFAULT_SIZE时,就要进行缩容
if(size(0)+size(1)==data.length/4&&data.length>DEFAULT_SIZE){
resize(data.length/2);
}
return ret;
}
private void resize(int newLength) {
E [] newData =(E [])new Object[newLength];
//先去处理左端栈的问题
for(int i=0;i<=ltop;i++){
newData[i]=data[i];
}
//再去处理右端栈
int index= rtop;
for(int i=newLength-size(1);i<newLength;i++){
newData[i]=data[index++];
}
rtop=newLength-size(1);
data =newData;
}
public int size(int stackId){
switch (stackId){
case 0:
return ltop+1;
case 1:
return data.length-rtop;
}
return -1;
}
//判断某一端的栈是否为空
private boolean isEmpty(int stackId) {
switch(stackId){
case 0:
return ltop==-1;
case 1:
return rtop ==data.length;
}
return false;//防止程序报错
}
public E peek(int stackId){
if(isEmpty(stackId)){
throw new NullPointerException("stack is null");
}
switch (stackId){
case 0:
return data[ltop];
case 1:
return data[rtop];
}
return null;
}
public void clear(int stackId){
switch(stackId){
case 0:
ltop=-1;
break;
case 1:
rtop =data.length;
}
}
public String toString(){
StringBuilder sb =new StringBuilder(String.format("ArrayDoubleEndStack:%d/%d\n",size(0)+size(1),data.length));
if(isEmpty(0)){
sb.append("leftStack:[]\n");
}
else{
sb.append("leftStack:[");
for(int i=0;i<=ltop;i++){
sb.append(data[i]);
if(i==ltop){
sb.append(']');
sb.append('\n');
}
else{
sb.append(',');
}
}
}
if(isEmpty(1)){
sb.append("rightStack:[]");
}
else{
sb.append("rightStack:[");
for(int i= data.length-1;i>=rtop;i--){
sb.append(data[i]);
if(i==rtop){
sb.append(']');
sb.append('\n');