数据结构与算法java实战篇--栈和队列

目录

一.栈

二.队列

三.双端队列

四.优先级队列


一.栈

        栈只有一个出口,元素先进后出,从栈顶进入从栈顶取出,先进的元素先到栈底

  栈代码实例:

class Stack{
    private int MaxSize;    //栈的长度
    private long[] SatckArray;
    private int top;    //栈顶

    public Stack(int s){    //初始化栈
        MaxSize=s;
        SatckArray=new long[MaxSize];
        top=-1;
    }

    public void push(long j){   //入栈
        SatckArray[++top]=j;
    }

    public long pop(){  //出栈
        return SatckArray[top--];
    }

    public long peek(){     //获取栈顶元素
        return SatckArray[top];
    }

    public boolean isEpty(){  //判断栈是否为空
        return (top==-1);
    }

    public boolean isFull(){   //判断栈是否满
        return (top==MaxSize-1);
    }

}

二.队列

        队列是一种数据结构,类似于栈结构,只不过队列结构的数据先进先出(FIFO)

队列代码实例:

class Queue{
    private int MaxSize;
    private long[] QueArray;
    private int front;
    private int rear;
    private int nltems;

    public Queue(int s){    //队列初始化
        MaxSize=s;
        QueArray=new long[MaxSize];
        front=0;
        rear=-1;
        nltems=0;
    }

    public void insert(long j){     //元素从队尾入队
        if (rear==MaxSize-1)    //如果队列满了,重置rear
            rear=-1;
        QueArray[++rear]=j;
        nltems++;
    }

    public long romve(){    //元素从队首出队
        long temp=QueArray[front++];
        if (front==MaxSize)   //如果移除最后一个元素,重置front
            front=0;
        nltems--;
        return temp;
    }

    public long peekFront(){    //获取队首
        return QueArray[front];
    }

    public boolean isEmpty(){   //判断是否为空
        return (nltems==0);
    }

    public boolean isFull(){    //判断是队列是否满了
        return (nltems==MaxSize);
    }

    public int size(){      //元素个数
        return nltems;
    }
}

三.双端队列

        双端队列是一种特殊的队列,它两端都可以插入元素,同时两端也都可以取出元素

Java中的双端队列收集

 双端队列代码实例:

class MyDeque<E> {
    //默认容量
    private static final int DEFAULT_CAPACITY = 8;
    //最大容量
    private static final int MAX_CAPACITY = Integer.MAX_VALUE;

    //存储数组
    private Object[] elements;
    //队列头
    private int head;
    //队列尾
    private int tail;
    //队列元素个数
    private int size;

    //无参构造器,使用默认容量初始化
    public MyDeque() {
        //初始化
        this.elements = new Object[DEFAULT_CAPACITY];
        this.head = 0;
        this.tail = 0;
        this.size = 0;
    }

    //指定容量大小的构造器
    public MyDeque(int capacity) {
        //合法性检查
        if (capacity < 0 || capacity > MAX_CAPACITY) {
            throw new IllegalArgumentException("parameter is illegal");
        }
        //使用给定的容量初始化
        this.elements = new Object[capacity];
        this.head = 0;
        this.tail = 0;
        this.size = 0;
    }

    /**
     * 在双端队列的开头添加指定的元素。
     *
     * @param element 要添加的元素
     * @return 是否添加成功
     */
    public boolean offerFirst(E element) {
        //判断队列是否满了
        if (size == elements.length) {
            doubleCapacity();
        }
        //如果队列为空
        if (isEmpty()) {
            elements[head] = element;
        } else {
            //添加元素到队列头,head左移
            elements[getRealIndex(head - 1)] = element;
            //更新队列状态
            head = getRealIndex(head - 1);
        }
        size++;
        return true;
    }

    /**
     * 在双端队列的尾部添加指定的元素。
     *
     * @param element 要添加的元素
     * @return 是否添加成功
     */
    public boolean offerLast(E element) {
        //判断队列是否满了
        if (size == elements.length) {
            doubleCapacity();
        }
        //如果队列为空
        if (isEmpty()) {
            elements[tail] = element;
        } else {
            //添加元素到队列尾,tail右移
            elements[getRealIndex(tail + 1)] = element;
            //更新队列状态
            tail = getRealIndex(tail + 1);
        }
        size++;
        return true;
    }


    /**
     * 返回并删除双端队列的队头元素。如果双端队列为空,则返回null。
     *
     * @return
     */
    public E pollFirst() {
        //判断队列是否为空
        if (isEmpty()) return null;
        //删除除队列的第一个元素
        E removedElement = (E) elements[head];
        elements[head] = null;
        //head右移
        head = getRealIndex(head + 1);
        size--;
        return removedElement;
    }

    /**
     * 返回并删除双端队列的队尾元素。如果双端队列为空,则返回null。
     *
     * @return
     */
    public E pollLast() {
        //判断队列是否为空
        if (isEmpty()) return null;
        //删除除队列的第一个元素
        E removedElement = (E) elements[tail];
        elements[tail] = null;
        //tail左移
        tail = getRealIndex(tail - 1);
        size--;
        return removedElement;
    }

    /**
     * 返回双端队列的第一个元素。如果双端队列为空,则返回null。
     *
     * @return
     */
    public E peekFirst() {
        if (isEmpty()) return null;
        return (E) elements[head];
    }

    /**
     * 返回双端队列的最后一个元素。如果双端队列为空,则返回null。
     *
     * @return
     */
    public E peekLast() {
        if (isEmpty()) return null;
        return (E) elements[tail];
    }


    /**
     * 判断队列是否为空
     *
     * @return true:为空 false:不为空
     */
    public boolean isEmpty() {
        return size == 0;
    }

    /**
     * 扩增队列容量
     */
    public void doubleCapacity() {
        //检查队列是否已达到上限
        if (elements.length == MAX_CAPACITY) throw new RuntimeException("deque is full");
        //新的队列容量为目前的两倍
        int newCapacity = elements.length * 2;
        //检查新容量是否超过最大容量限制
        if (newCapacity > MAX_CAPACITY) newCapacity = MAX_CAPACITY;
        //使用新容量构造一个新的数组
        Object[] newArr = new Object[newCapacity];
        //把元素移动到新的数组中
        for (int i = 0; i < elements.length; i++) {
            newArr[i] = elements[getRealIndex(head + i)];
        }
        //更新队列状态
        head = 0;
        tail = elements.length - 1;
        elements = newArr;
    }

    /**
     * 获取真实下标
     *
     * @param logicIndex 逻辑下标
     * @return 真实下标
     */
    private int getRealIndex(int logicIndex) {
        int innerArrayLength = elements.length;
        //逻辑下标小于0
        if (logicIndex < 0) {
            //加上当前数组的长度
            logicIndex += innerArrayLength;
        }
        //逻辑下标大于等于数组长度
        if (logicIndex >= innerArrayLength) {
            //减去当前数组的长度
            logicIndex -= innerArrayLength;
        }
        //返回真实下标
        return logicIndex;
    }

    /**
     * 打印deque
     */
    public void printDeque() {
        for (int i = 0; i < elements.length; i++) {
            if (elements[getRealIndex(head + i)] == null) break;
            System.out.print(elements[getRealIndex(head + i)].toString());
            System.out.print("-->");
        }
        System.out.println("\b\b\b");
    }
}

四.优先级队列

        和普通队列一样,优先级队列有一个对列头和一个队列尾,但优先级队列的数据按一定的条件给队列中数据排序

优先级队列代码实例:

class priorityQ{
    private int MaxSize;
    private long[] queArray;
    private int nltems;

    public priorityQ(int s){    //初始化队列
        MaxSize=s;
        queArray=new long[MaxSize];
        nltems=0;
    }

    public void inser(long item) {
        int j;
        if (nltems == 0) {
            queArray[nltems++] = item;
        } else {
            for (j = nltems - 1; j >= 0; j--) {
                if (item > queArray[j])   //设置优先级
                    queArray[j + 1] = queArray[j];
                else break;
            }
            queArray[j + 1] = item;
            nltems++;
        }
    }

    public long remove(){
        return queArray[--nltems];
    }

    public long peekmin(){
        return queArray[nltems-1];
    }

    public boolean isEpty(){
        return (nltems==0);
    }

    public boolean isFull(){
        return (nltems==MaxSize);
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前段被迫创业

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值