相比普通栈的问题:
1. 扩缩容都是将原先的数组元素移到一个新的数组中
2. 左端栈直接对应的角标移动就好
3. 而右端栈麻烦点需要找一个关系,
4. 扩缩容之后新的rtop=新数组长度-右端栈的元素个数
5. 最后再把新数组地址赋给原先数组:data=newData
双端栈是限定插入和删除操作在表的两端进行的线性表 是一种栈的的数据结构
双端栈左边空: ltop == -1; 右边空: rtop == data.length;
双端栈满时:ltop +1 == rtop
代码实现:
public class ArrayDoubleEndStack<E> implements Iterable<E>{
//左端栈顶
private int ltop;
private int rtop;
//容器
private E[] data;
private static int DEFAULT_CAPACITY = 10;
public ArrayDoubleEndStack(){
data= (E[]) new Object[DEFAULT_CAPACITY];
ltop = -1;
rtop = data.length;
}
public void pushLeft(E element){
// ltop++;
// data[ltop] = element;
if (ltop +1 == rtop){
resize(data.length*2);
}
data[++ltop] = element;
}
public void pushRight(E element){
if (ltop+1 == rtop){
resize(data.length*2);
}
data[--rtop] = element;
}
public E peekLeft(){
if (isLeftEmpty()){
throw new IllegalArgumentException(" lest stack is null");
}
return data[ltop];
}
public E peekRight(){
if (isRightEmpty()){
throw new IllegalArgumentException(" lest stack is null");
}
return data[rtop];
}
private void resize(int newLen) {
E[] newdata = (E[]) new Object[newLen];
for (int i = 0;i<=ltop;i++){
newdata[i] = data[i];
}
//复制右端
int index = rtop;
for (int i = newLen-sizeRight();i<newLen;i++){
newdata[i] = data[index++];
}
rtop = newLen-sizeRight();
data = newdata;
}
public E popLeft(){
if (isLeftEmpty()){
throw new IllegalArgumentException("left stack is null");
}
E ret = data[ltop--];
if (sizeLeft()+sizeRight() <= data.length / 4 && data.length > DEFAULT_CAPACITY){
resize(data.length/2);
}
return ret;
}
public E popRight(){
if (isRightEmpty()){
throw new IllegalArgumentException("");
}
E ret = data[rtop++];
if (sizeLeft()+sizeRight() <= data.length / 4 && data.length > DEFAULT_CAPACITY){
resize(data.length/2);
}
return ret;
}
public boolean isLeftEmpty(){
return ltop == -1;
}
public boolean isRightEmpty(){
return rtop == data.length;
}
public int sizeLeft(){
return ltop+1;
}
public int sizeRight(){
return (data.length-rtop);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append('[');
if (isLeftEmpty() && isRightEmpty()){
sb.append(']');
return sb.toString();
}
for (int i = 0;i<ltop;i++){
sb.append(data[i]);
if (i == ltop && isRightEmpty()){
sb.append(']');
}else {
sb.append(',');
}
}
//右边
for (int i = rtop; i< data.length;i++){
sb.append(data[i]);
if (i == data.length-1){
sb.append(']');
}else {
sb.append(',');
}
}
return sb.toString();
}
@Override
public Iterator<E> iterator() {
return new ArrayDoubleEndStackIterator();
}
class ArrayDoubleEndStackIterator implements Iterator<E>{
private Iterator<E> it;
private ArrayList<E> list;
public ArrayDoubleEndStackIterator() {
list = new ArrayList<>();
for (int i =0;i<ltop; i++){
list.add(data[i]);
}
for (int i = rtop ; i < data.length;i++){
list.add(data[i]);
}
it = list.iterator();
}
@Override
public boolean hasNext() {
return it.hasNext();
}
@Override
public E next() {
return it.next();
}
}
}