双端链栈的定义
链栈是基于链表实现的,双端链栈不基于链表实现了,因为双端有两个栈顶,即左右共有两个虚拟头结点,一个链表不支持该操作。
双端链栈的进栈和出栈
因栈都是在栈顶进行操作的,所以此时尾指针就没了作用,要想使时间复杂度为O(1),所以进栈和出栈操作都使用头插和头删,都是在头结点之后进行操作。
public void leftpush(E e){
//将left的下一跳赋给即将要进栈的结点的下一
//然后left的下一跳就为新结点,然后长度加1
left.next=new Node(e,left.next);
leftsize++;
}//在节点中间头插法
public void rightpush(E e){
right.next=new Node(e,right.next);
rightsize++;
}
双端链栈的判空
如果双端链栈为空,即左边和右边的有效元素长度都为0,且左头结点left的下一跳是右头结点right,且右头结点right的下一跳是空。
public boolean isleftEmpty(){
return left.next==right&&leftsize==0;
}
public boolean isrightEmpty(){
return right.next==null&&rightsize==0;
}
整体代码
package Ds02.动态链表;
import DS01.动态数组.Stack;
import java.util.Iterator;
//不能基于链表实现了,因为有两个栈顶,有两个虚拟头结点
//无论是链栈还是双端链栈都是在虚拟头结点之后的第一个结点进行操作的,意思就是
//在头进行操作,因为时间复杂度是O(1)
public class LinkStackDoubleEnd<E> implements Stack<E> {
private Node left;
private Node right;
private int leftsize;
private int rightsize;
public LinkStackDoubleEnd(){//初始化创建两个结点,左结点右结点
left=new Node();
right=new Node();
leftsize=0;
rightsize=0;
left.next=right;
}
private class Node{//内部类(结点的属性与行为)
E data;//数据域
Node next;//指针域,因为存下一个节点,节点类型为Node
Node(){
this(null,null);
}
Node(E data, Node next){
this.data=data;
this.next=next;
}
@Override
public String toString(){
return data.toString();
}
}
@Override
public int getSize() {
return leftsize+rightsize;
}
public int getleftsize(){
return leftsize;
}
public int getrightsize(){
return rightsize;
}
@Override
public boolean isEmpty() {
return isleftEmpty()&&isrightEmpty();
}
public boolean isleftEmpty(){
return left.next==right&&leftsize==0;
}
public boolean isrightEmpty(){
return right.next==null&&rightsize==0;
}
@Override
public E pop() {
return leftsize>=rightsize?leftPop():rightPop();
}
public E leftPop(){
if(isleftEmpty()){
throw new IllegalArgumentException("左栈为空");
}
E ret=left.next.data;
left.next=left.next.next;
leftsize--;
return ret;
}
public E rightPop(){
if(isrightEmpty()){
throw new IllegalArgumentException("右栈为空");
}
E ret=right.next.data;
right.next=right.next.next;
rightsize--;
return ret;
}
@Override
public void push(E e) {
if(leftsize>=rightsize){
leftpush(e);
}else{
rightpush(e) ;
}
}
public void leftpush(E e){
left.next=new Node(e,left.next);
leftsize++;
}//在节点中间头插法
public void rightpush(E e){
right.next=new Node(e,right.next);
rightsize++;
}
@Override
public E peek() {
return leftsize>=rightsize?leftPeek():rightpeek();
}
public E leftPeek(){
if(isleftEmpty()){
throw new IllegalArgumentException("左边为空");
}
return left.next.data;
}
public E rightpeek(){
if(isrightEmpty()){
throw new IllegalArgumentException("右边为空");
}
return right.next.data;
}
@Override
public void clear() {
left.next=right;
leftsize=0;
rightsize=0;
}
public void clearLeft(){
left.next=right;
leftsize=0;
}
public void clearRight(){
right.next=null;
rightsize=0;
}
@Override
public Iterator<E> iterator() {
return null;
}
}