栈和队列 【数据结构】

但若返回-1,就不清楚是出队列失败返回的-1,还是本来就返回的是-1,故 -1 不能做非法值

Integer 包装类,也是一个引用类型的对象,引用类型就可以是一个空引用,就可以表示非法情况

.

故:此处返回值不用 int,使用 Integer

.在这里插入图片描述

以数组为例

一般我们会想到,入队列,即在数组后插入一个元素

而出队列,就会依次覆盖前一个元素(搬运操作),但这样效率会比较低

下图所展现的过程就是低效的搬运过程:

在这里插入图片描述

循环队列(高效操作)

不用搬运也可完成出队列操作

画图表示:

在这里插入图片描述

当前队列中的有效元素就算是 [head,tail)

head 始终就是队首元素,tail 始终就是队尾的下一个元素

当 head 和 tail 重合时,此时队列为空

在这里插入图片描述

有效元素的情况:

  • tail 在前,head 在后

在这里插入图片描述

  • tail 在前,head 在后

在这里插入图片描述

  • head 和 tail 重合

当 head 和 tail 重合时,可能是空队列也可能是满队列

  1. 空队列

在这里插入图片描述

  1. 满队列

在这里插入图片描述

模拟实现:

public class MyQueue2 {

private int[] array = new int[100];

//size 表示元素个数

private int size = 0;

// [head,tail) 表示有效元素,但tail 可能在 head之前

private int head = 0;

private int tail = 0;

//入队列

public void offer(int val){

//判定是否为满队列

if(size == array.length){

System.out.println(“队列已满,无法插入!”);

return;

}

array[tail] = val;

tail++;

//若tail++,超出了数组的有效范围,那么让tail从0开始

if(tail >= array.length){

tail = 0;

}

size++;

}

//出队列

public Integer poll(){

//判定是否为空队列

if(size == 0){

System.out.println(“队列为空,无法删除!”);

return null;

}

Integer ret = array[head];

head++;

if(head >= array.length){

head = 0;

}

size–;

return ret;

}

//取队首元素

public Integer peek(){

//判定是否为空队列

if(size == 0){

return 0;

}

return array[head];

}

}

栈和队列实现起来非常容易,复杂的就是结合实际场景来使用

栈和队列的方法

==================================================================

栈的方法

| 方法 | 作用 |

| — | — |

| Stack( ) | 定义一个空栈 |

| push( ) | 入栈 |

| pop( ) | 出栈(栈顶值) |

| peek( ) | 取栈顶值(不出栈) |

| empty( ) | 判断栈是否为空 |

代码示例:

public static void main(String[] args) {

Stack stack = new Stack<>();

//入栈

stack.push(1);

stack.push(2);

stack.push(3);

stack.push(4);

stack.push(5);

System.out.println(stack.empty());

//出栈

int ret = stack.pop();

System.out.println(ret); //5

ret = stack.pop();

System.out.println(ret); //4

ret = stack.pop();

System.out.println(ret); //3

ret = stack.pop();

System.out.println(ret); //2

ret = stack.pop();

System.out.println(ret); //1

System.out.println(stack.empty());

}

输出结果:

在这里插入图片描述

验证了栈的 先进后出 的特性

若为空栈,在进行出栈,则可能发生异常

public static void main(String[] args) {

Stack stack = new Stack<>();

//入栈

stack.push(1);

//出栈

int ret = stack.pop();

System.out.println(ret);

ret = stack.pop();

System.out.println(ret);

}

在这里插入图片描述

标准库中的 Stack 如果为空,再次 pop / peek,都会抛出异常

队列的方法

一般建议使用 offer( ),poll( ),peek( ) 这组操作

| 方法 | 作用 | 错误处理 |

| — | — | — |

| offer( ) | 将指定元素插入队列 | 成功返回 true,否则返回 false |

| poll( ) | 取并移除队首元素 (出队列) | 队列为空,返回null |

| peek( ) | 取队首元素,但不出队列 | 队列为空,返回null |

| add( ) | 入队列 | 抛出 IllegalStateException 异常 |

| remove( ) | 取并移出队首元素(出队列) | 队列为空,抛出 NoSuchElementException 异常 |

| element( ) | 取队首元素,但不出队列 | 队列为空,抛出 NoSuchElementException 异常 |

  • ①add( ) remove( ) element( ) 示例:

public static void main(String[] args) {

//初始化

Queue queue = new LinkedList<>();

//入队列

queue.add(1);

queue.add(2);

queue.add(3);

queue.add(4);

//取队首元素 (不出队列)

System.out.println(“使用element()取队首元素…”);

System.out.println(queue.element());

System.out.println();

//出队列

System.out.println(“使用remove()出队列…”);

System.out.println(queue.remove());

System.out.println(queue.remove());

System.out.println(queue.remove());

System.out.println(queue.remove());

}

输出结果:

在这里插入图片描述

验证了队列的 先进先出 的特性

特殊情况:

  • 队列为空,取队首元素

public static void main(String[] args) {

  Queue<Integer> queue = new LinkedList<>();
  //取队首元素 (不出队列)
  System.out.println("使用element()取队首元素....");

System.out.println(queue.element());

System.out.println();

}

输出结果:

.在这里插入图片描述

.

  • 队列为空,出队列

public static void main(String[] args) {

Queue queue = new LinkedList<>();

//出队列

System.out.println(“使用remove()出队列…”);

System.out.println(queue.remove());

}

输出结果:

.

在这里插入图片描述

  • ②offer( ),poll( ),peek( ) 示例:

public static void main(String[] args) {

//初始化

Queue queue = new LinkedList<>();

//将指定元素插入队列

queue.offer(66);

queue.offer(88);

queue.offer(99);

System.out.println();

//取队首元素

System.out.println(“使用peek()取队首元素…”);

System.out.println(queue.peek());

System.out.println();

//出队列

System.out.println(“使用poll()出队列…”);

System.out.println(queue.poll());

System.out.println(queue.poll());

System.out.println(queue.poll());

}

输出结果:

在这里插入图片描述

特殊情况:

  • 队列为空,取队首元素

public static void main(String[] args) {

//初始化

Queue queue = new LinkedList<>();

//取队首元素

System.out.println(“使用peek()取队首元素…”);

System.out.println(queue.peek());

System.out.println();

}

输出结果:

.在这里插入图片描述

.

  • 队列为空,出队列

public static void main(String[] args) {

//初始化

Queue queue = new LinkedList<>();

//出队列

System.out.println(“使用poll()出队列…”);

System.out.println(queue.poll());

System.out.println();

}

输出结果:

.在这里插入图片描述

由上述例子可知,第①组操作失败就会抛出异常,第②组操作失败会返回一个错误值

故:一般建议使用 offer( ),poll( ),peek( ) 这组操作
下篇我们会讨论有关栈和队列的面试题~~
在这里插入图片描述

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

最后总结

ActiveMQ+Kafka+RabbitMQ学习笔记PDF

image.png

  • RabbitMQ实战指南

image.png

  • 手写RocketMQ笔记

image.png

  • 手写“Kafka笔记”

image

关于分布式,限流+缓存+缓存,这三大技术(包含:ZooKeeper+Nginx+MongoDB+memcached+Redis+ActiveMQ+Kafka+RabbitMQ)等等。这些相关的面试也好,还有手写以及学习的笔记PDF,都是啃透分布式技术必不可少的宝藏。以上的每一个专题每一个小分类都有相关的介绍,并且小编也已经将其整理成PDF啦
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
mg-community.csdnimg.cn/images/e5c14a7895254671a72faed303032d36.jpg" alt=“img” style=“zoom: 33%;” />

最后总结

ActiveMQ+Kafka+RabbitMQ学习笔记PDF

[外链图片转存中…(img-IyihHSze-1713738586554)]

  • RabbitMQ实战指南

[外链图片转存中…(img-Knp7zaBC-1713738586554)]

  • 手写RocketMQ笔记

[外链图片转存中…(img-zJs8BlvD-1713738586554)]

  • 手写“Kafka笔记”

[外链图片转存中…(img-lX3wiTww-1713738586555)]

关于分布式,限流+缓存+缓存,这三大技术(包含:ZooKeeper+Nginx+MongoDB+memcached+Redis+ActiveMQ+Kafka+RabbitMQ)等等。这些相关的面试也好,还有手写以及学习的笔记PDF,都是啃透分布式技术必不可少的宝藏。以上的每一个专题每一个小分类都有相关的介绍,并且小编也已经将其整理成PDF啦
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值