用数组实现队列和栈

1.数组实现队列

1.定义队列的接口

public interface MyQueue {
    int size();   //获取队列的容量大小
    boolean isEmpty();   //判断队列是否为空
    void offer(Integer value);   //将元素从队列尾部加入
    int poll();   //将元素从队列头部删除
    int peek();   //获取队列头部元素

}

2.设计接口的实现类
首先准备一个数组,一个头指针和一个尾指针,我们用尾指针作为游标来控制入队的元素,用头指针来控制出队的元素,当两个指针在同一个位置时,就表示队列为空,另外对列头部元素,我们用first指针下一个位置元素来表示,队列的容量用两个指针间的距离来表示。
对于offer方法,当队列满了,就抛异常,如果没满,我们就将last后移,并赋值为待入队元素。
对于poll方法,当队列为空时,直接抛异常,如果不为空,我们先记录队头元素,然后将原来队列头部置为0,最后返回记录到的元素。

public class ArrayQueue implements MyQueue{
    private int N=10;
    private int[] arr=new int[N];
    private int first=-1;
    private int last=-1;

    ArrayQueue(){}

    ArrayQueue(int capacity){
        this.N=capacity;
    }

    @Override
    public int size() {
        return last-first;
    }

    @Override
    public boolean isEmpty() {
        return first==last;
    }

    @Override
    public void offer(Integer value) {
        if(size()==N){
            throw new ArrayIndexOutOfBoundsException("队列已经满了,不能再加数据!");
        }
        arr[++last]=value;
    }

    @Override
    public int poll() {
        if(isEmpty()){
            throw new ArrayIndexOutOfBoundsException("队列已经空了,没有数据!");
        }
        int value=arr[first+1];
        arr[++first]=0;
        return value;
    }

    @Override
    public int peek() {
        if(isEmpty()){
            throw new ArrayIndexOutOfBoundsException("队列已经空了,没有数据!");
        }
        return arr[first+1];
    }
}

3.验证设计的正确性

public class Main {
    public static void main(String[] args){
        ArrayQueue queue=new ArrayQueue();
        queue.offer(1);
        queue.offer(2);
        queue.offer(4);
        queue.offer(3);
        queue.offer(5);
        System.out.println(queue.isEmpty());
        System.out.println(queue.peek());
        queue.poll();
        System.out.println(queue.poll());
        System.out.println(queue.peek());

    }
}

最终打印的结果:
在这里插入图片描述

2.数组实现栈

1.定义栈的接口

public interface MyStack {
    int size();   //获取栈的容量大小
    boolean isEmpty();   //判断栈是否为空
    void push(Integer value);   //将元素从栈顶压入
    int pop();   //将元素从栈顶弹出
    int peek();   //获取栈顶元素
}

2.设计接口的实现类
既然是数组实现,我们首先准备一个大小为10的数组(参考ArrayList的源码),然后准备一个记录栈容量大小的变量N,由于入栈和压栈只在栈顶进行,所以我们只需关注栈顶的下标和对应元素。
对于push的实现,当压入一个元素时,可能容量会超出初始设定的数值,所以先判断是否需要扩容,如果不需要,跳过扩容操作,直接设置N下标对应元素为入栈的元素,并跟新容量大小;如果需要扩容,先新建一个容量大小为原来2倍的临时数组,然后把原数组值全部复制到临时数组,最后再将原数组替换为临时数组,完成扩容。(如果不考虑扩容,直接抛异常)
对于pop的实现,首先进行判空操作,如果为空,则直接返回-1;然后记录弹出元素,并将弹出位置值重设为0(就想象是正常push的逆操作)。

public class ArrayStack implements MyStack{
    private int[] arr=new int[10];
    private int N=0;

    @Override
    public int size() {
        return N;
    }

    @Override
    public boolean isEmpty() {
        return N==0;
    }

    @Override
    public void push(Integer value) {
        check();
        arr[N]=value;
        N++;
    }

    @Override
    public int pop() {
        if(isEmpty()){
            return -1;
        }

        int value=arr[--N];
        arr[N]=0;
        return value;
    }

    @Override
    public int peek() {
        if(isEmpty()){
            return -1;
        }
        return arr[N-1];
    }

    /**
     * 判断是否超过原始设置容量,如果超过,则扩容为原来的2倍
     */
    private void check(){
        if(N>=arr.length){
            resize(2*arr.length);
        }
    }

    /**
     * 扩容
     * @param size 扩容后的容量大小
     */
    private void resize(int size){
        int[] temp=new int[size];
        for(int i=0;i<N;i++){
            temp[i]=arr[i];
        }
        arr=temp;
    }
}

3.验证设计的正确性

public class Main {
    public static void main(String[] args){
        ArrayStack stack=new ArrayStack();
        stack.push(1);
        stack.push(3);
        stack.push(2);
        stack.push(5);
        stack.push(4);
        System.out.println(stack.isEmpty());
        System.out.println(stack.peek());
        System.out.println(stack.size()+"----");
        stack.pop();
        System.out.println(stack.size()+"----");
        System.out.println(stack.pop());
        System.out.println(stack.size()+"----");
        System.out.println(stack.peek());
    }
}

最终打印的结果:
在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值