双端栈的定义
指线性表的两边当作栈底进行入栈出栈操作
双端栈的主要功能
//特殊情况的线性表
public interface Stack<E> extends Iterable<E>{
int getSize(); //获取栈元素个数
boolean isEmpty(); //栈判空
void push(E e); //进栈
E pop(); //出栈
E peek(); //查看当前栈顶
void clear(); //清空栈
}
双端栈功能的具体实现:
package DS01.动态数组;
import java.util.Iterator;
//双端栈
public class ArrayStackDoubleEnd <E> implements Stack<E>{
private static final int DEFAULT_SIZE=10;
private E [] data;
private int leftTop;
private int rightTop;
public int getDatLength(){//双端栈的无参构造函数
return data.length;
}
public ArrayStackDoubleEnd(){ //双端栈的有参构造函数
this(DEFAULT_SIZE);
}
public ArrayStackDoubleEnd(int capacity){ //双端栈的有参构造函数
data=(E[])new Object[capacity];
leftTop=-1;
rightTop=data.length;
}
public int getLeftSize(){ //获取左栈有效元素
return leftTop+1;
}
public int getRightSize(){ //获取右栈有效元素
return data.length-rightTop;
}
@Override
public int getSize() { //获取有效元素
return getLeftSize()+getRightSize();
}
public boolean isLeftEmpty(){ //判断左栈是否为空
return getLeftSize()==-1;
}
public boolean isRightEmpty(){ //判断右栈是否为空
return getRightSize()==data.length;
}
@Override
public boolean isEmpty() { //判断双端栈是否为空
return isLeftEmpty()&&isRightEmpty();
}
public void liftPush(E e){ //左端进栈
if(leftTop+1==rightTop){
//扩容
resize(data.length*2);
}
leftTop++;
data[leftTop]=e;
}
public void rightPush(E e){ //右端进栈
if(leftTop+1==rightTop){
resize(data.length*2);
}
rightTop--;
data[rightTop]=e;
}
private void resize(int length){ //双端栈的扩容和缩容
E [] newData=(E[])new Object [length];
for(int i=0;i<=getLeftSize();i++){
newData[i]=data[i];
}
int a=newData.length-1;
for(int i=data.length-1;i>=data.length-getRightSize()-1;i--){
newData[a--]=data[i];
}
rightTop=a+1;
data=newData;
}
@Override
public void push(E e) { //进栈操作
if(getRightSize()>getLeftSize()){
liftPush(e);
}else{
rightPush(e);
}
}
public E liftPop(){ //左边出栈
if(isLeftEmpty()){
throw new IllegalArgumentException("左栈为空");
}
if(getSize()>=10&&(data.length/4)>getSize()){
resize(data.length/2);
}
return data[leftTop--];
}
public E rightPop(){ //右边出栈
if(isRightEmpty()){
throw new IllegalArgumentException("右栈为空");
}
if(getSize()-1>=10&&data.length/4>getSize()){
resize(data.length/2);
}
return data[rightTop++];
}
@Override
public E pop() { //出栈操作
if(getRightSize()>getLeftSize()){
return rightPop();
}else{
return liftPop();
}
}
public E peekLift(){ //查看左边栈顶
if(isLeftEmpty()){
throw new IllegalArgumentException("栈为空");
}
return data[leftTop];
}
public E peekRight(){ //查看右边栈顶
if(isRightEmpty()){
throw new IllegalArgumentException("栈为空");
}
return data[rightTop];
}
@Override
public E peek() { //查看元素多的栈顶
return getLeftSize()>getRightSize()?peekLift():peekRight();
}
@Override
public void clear() { //清除栈
data=(E[])new Object[DEFAULT_SIZE];
leftTop=-1;
rightTop=data.length;
}
public String toString(){ //打印toString
StringBuilder s=new StringBuilder();
s.append(String.format("ArrayStackDoubleEnd:%d/%d\n",getSize(),data.length));
if(isLeftEmpty()){
s.append("左边为空\n");
}else{
s.append("左边:[");
for(int i=0;i<=leftTop;i++){
s.append(data[i]);
if(i==leftTop){
s.append("]\n");
}else{
s.append(',');
}
}
}
if(isRightEmpty()){
s.append("右边为空\n");
}else{
s.append("右边:[");
for(int i=rightTop;i<data.length;i++){
s.append(data[i]);
if(i==data.length-1){
s.append(']');
}else{
s.append(',');
}
}
}
return s.toString();
}
@Override
public Iterator<E> iterator() {
return null;
}
}