请你用数组来实现队列和栈(大厂经典面试题)

请你用数组来实现队列和栈(大厂经典面试题)

提示:之前我们说过用双向队列实现栈和队列,贼简单
栈和队列,双端队列,如何用链表实现双端队列,如何用双端队列实现栈和队列

现在,用数组实现队列和栈,这样遍历速度快


数组实现队列

咋做呢?
关键在模拟队列的先进先出
数组目前定长为N=limit,咱们让数组arr的左边为出,而arr的右边为入,这样的话,来一个数放在数组右边,弹出一个的话,从左边拿。
(0)每一次存入一个数,push(value),则size++,记录真实存入数的量;
在这里插入图片描述
(1)你真实存入数组中的数目size,如果到了N,说明不能再存了,返回队列已满!
在这里插入图片描述
(2)如果下一次再来新的数,咱们需要在上一次放的数的下一个位置放,代表我后来的;
而且size<N时,当放入的数到了N-1位置,本次的数就要去0位置继续放;
也就是说,咱们要是让pushi做即将放入新数的下标的话,如果本次pushi放在N-1,下一次就得循环倒回去0位置。
在这里插入图片描述
(3)只要size>0,你就能poll(),咱们得找到哪个数最先进来的,让它先出去,这就是队列的本质!!
我们这样吧,单独让polli做要弹出的下标,最开始pulli=0,毕竟第一个进来的就是0位置,然后是1位置,递增
故,每次需要弹出时,咱们让size–,代表少了一个元素;
然后,ans=arr[polli],它就是要弹出的位置,
然后立马让polli++,代表下一次要弹出polli位置的数,因为递增的下标就是先进来的那些元素。
在这里插入图片描述
【但是要注意,这里是循环的下标推导,也就是当本次polli=N-1时,下一次polli要跟随输入那个数去0位置】
在这里插入图片描述

所以总结一下:
——当索引位置到N-1位置时,下一次应该去0位置:
代码:
//环形下标控制函数 public int nextIndex(int i){ return i < len - 1 ? i + 1 : 0;//如果i还没有到最后一个位置,递增,到了len-1则去0 }
用arr替代链表做队列,让pushi单独做输入数据的索引下标,让polli单独做弹出元素的下标,两者都是递增的规律,保证先进先出
size用来表示实际的输入元素,push则size++,poll则size–
反正保证size>0或者size<=N,才有效
在这里插入图片描述
手撕数组实现队列的结构:
手撕之前,我想说:java中的构造函数,如果你构造函数中的变量N和属性变量this.N名字一样,是没法赋值成功的
在这里插入图片描述
必须用下面两种方式:
(1)this.N = N;
(2)将构造函数中的N改为别的名字,比如Nx

public ReviewQueuebyArray(int Nx){
            //构造函数说明清楚队列的大小
            N = Nx;
            arr = new int[N];

只有这样才能赋值成功,这是代码高手可能都会忽略的问题……

//复习数组实现队列
    public static class ReviewQueuebyArray{
        public int[] arr;
        private int pushi;
        private int polli;
        private int N;
        private int size;

        public ReviewQueuebyArray(int Nx){
            //构造函数说明清楚队列的大小
            N = Nx;
            arr = new int[N];
            pushi = 0;
            polli = 0;//这俩都默认为0
            size = 0;//最开始没有数
        }

        //循环递推下标的函数
        private int nextIndex(int N, int i){
            return i == N - 1 ? 0 : i + 1;//遇到N-1,下一次去0,否则i++
        }

        //判空
        public boolean isEmpty(){
            return size == 0;//没有实际存一个数,就是空
        }

        //push函数
        public void push(int value){
            //检查size
            if (size == N) throw new RuntimeException("没有空间了哦!");
            arr[pushi] = value;
            size++;
            pushi = nextIndex(N, pushi);//循环递推下标
        }

        //poll函数
        public int poll(){
            //检查size
            if (size == 0) throw new RuntimeException("根本没有元素啊!");
            int ans = arr[polli];
            size--;
            polli = nextIndex(N, polli);//循环递推下标

            return ans;
        }
    }

    public static void test2(){
        ReviewQueuebyArray queuebyArray = new ReviewQueuebyArray(4);
        queuebyArray.push(1);
        queuebyArray.push(2);
        queuebyArray.push(3);
        //queuebyArray.push(4);

        int[] ans = queuebyArray.arr;
        for(Integer i: ans) System.out.print(i +" ");
        System.out.println();
        System.out.println("pushi:"+ queuebyArray.pushi);
        System.out.println("polli:"+ queuebyArray.polli);

    }

看:只压3个数的话,下一次就应该放pushi了

1 2 3 0 
pushi:3
polli:0

咱再弹出一个试试:System.out.println(queuebyArray.poll());
结果如下:

1
1 2 3 0 
pushi:3
polli:1

这样就完美滴将数组arr拿来实现队列了,关键就在size控制实际入的数,然后用pushi控制入的下标,polli控制弹出的下标。


数组实现栈

有了上面数组实现队列的经验,实现栈也是类似的道理的
先进后出
那数组arr放入仍然用pushi的话,实际上,弹出的话,就让pushi–,然后弹出arr[pushi]
非常简单,不是吗?
在这里插入图片描述
所以的话,咱也不需要统计size了,一个pushi就行,循环下标也不需要,因为你最多就只能放N个
手撕代码:

//复习数组实现栈,很简单,一个pushi搞定一切
    public static class ReviewStackbyArray{
        public int[] arr;
        private int pushi;
        private int N;

        public ReviewStackbyArray(int Nx){
            N = Nx;
            arr = new int[N];
            pushi = 0;
        }

        //判空
        public boolean isEmpty(){
            return pushi == 0;
        }

        //push
        public void push(int value){
            if (pushi == N) throw new RuntimeException("满了!");
            arr[pushi++] = value;//先赋值再加pushi
        }

        //pop
        public int pop(){
            if (pushi == 0) throw new RuntimeException("空的!");
            return arr[--pushi];//先减再加,非常简单。
        }
    }

    public static void test3(){
        ReviewStackbyArray stackbyArray = new ReviewStackbyArray(4);
        stackbyArray.push(1);
        stackbyArray.push(2);
        stackbyArray.push(3);
        System.out.println("此时的pushi:"+ stackbyArray.pushi);
        int[] ans = stackbyArray.arr;
        for(Integer i: ans) System.out.print(i +" ");

        System.out.println();
        System.out.println(stackbyArray.pop());
        System.out.println("此时的pushi:"+ stackbyArray.pushi);
    }

显然,这比数组实现队列简单多了
看结果:
最开始压入3个数,自然pushi=3

此时的pushi:3
1 2 3 0 
3
此时的pushi:2

然后弹出一个,自然pushi就要倒回来,此时的3已经无效了!
咱们就是通过pushi来控制,哪些是有效地栈中的数,哪些是无效的
如果有新的数来,则3会被覆盖的。


总结

提示:重要经验:

1)将数组arr拿来实现队列了,关键就在size控制实际入的数,然后用pushi控制入的下标,polli控制弹出的下标。
2)用数组arr实现栈,再简单不过了,一个pushi搞定压入弹出操作。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

冰露可乐

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

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

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

打赏作者

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

抵扣说明:

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

余额充值