数据结构动态数组之双端栈和队列基层实现

本文详细介绍了数据结构中的双端栈和队列,包括它们的定义、接口实现以及在实际应用中的使用。通过ArrayQueue类展示了队列的实现,探讨了队列的优化方法,如循环队列,以减少出队操作的时间复杂度。同时,文章还讨论了双端队列的概念及其与循环队列的相似之处。
摘要由CSDN通过智能技术生成

双端栈

定义:一个线性表的两端当做栈底分别进行入栈和出栈的操作,主要利用了栈"栈底位置不变,而栈顶位置动态变化"的特性。

我们把双端栈叫做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');
           
/* * 基于双向链表实现双端队列结构 */ package dsa; public class Deque_DLNode implements Deque { protected DLNode header;//指向头节点(哨兵) protected DLNode trailer;//指向尾节点(哨兵) protected int size;//队列中元素的数目 //构造函数 public Deque_DLNode() { header = new DLNode(); trailer = new DLNode(); header.setNext(trailer); trailer.setPrev(header); size = 0; } //返回队列中元素数目 public int getSize() { return size; } //判断队列是否为空 public boolean isEmpty() { return (0 == size) ? true : false; } //取首元素(但不删除) public Object first() throws ExceptionQueueEmpty { if (isEmpty()) throw new ExceptionQueueEmpty("意外:双端队列为空"); return header.getNext().getElem(); } //取末元素(但不删除) public Object last() throws ExceptionQueueEmpty { if (isEmpty()) throw new ExceptionQueueEmpty("意外:双端队列为空"); return trailer.getPrev().getElem(); } //在队列前端插入新节点 public void insertFirst(Object obj) { DLNode second = header.getNext(); DLNode first = new DLNode(obj, header, second); second.setPrev(first); header.setNext(first); size++; } //在队列后端插入新节点 public void insertLast(Object obj) { DLNode second = trailer.getPrev(); DLNode first = new DLNode(obj, second, trailer); second.setNext(first); trailer.setPrev(first); size++; } //删除首节点 public Object removeFirst() throws ExceptionQueueEmpty { if (isEmpty()) throw new ExceptionQueueEmpty("意外:双端队列为空"); DLNode first = header.getNext(); DLNode second = first.getNext(); Object obj = first.getElem(); header.setNext(second); second.setPrev(header); size--; return(obj); } //删除末节点 public Object removeLast() throws ExceptionQueueEmpty { if (isEmpty()) throw new ExceptionQueueEmpty("意外:双端队列为空"); DLNode first = trailer.getPrev(); DLNode second = first.getPrev(); Object obj = first.getElem(); trailer.setPrev(second); second.setNext(trailer); size--; return(obj); } //遍历 public void Traversal() { DLNode p = header.getNext(); while (p != trailer) { System.out.print(p.getElem()+" "); p = p.getNex
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值