目录
队列在使用时有以下方法:
注意:Queue是个接口,在实例化时必须实例化LinkedList的对象,因为LinkedList实现了Queue接口。
Queue<Integer> q = new LinkedList<>();
代码:
- public class Myqueue {
- class Node{
- public int val;
- public Node next;
- public Node(int val){
- this.val=val;
- }
- }
-
- public Node head;
- public Node last;
- public int size;
- }
(1)创建一个节点node。
(2)判断该head是否为null,若为null,则该node就是head和last。
(3)若不为null,则 last.next=node, last=node;
(4)size++。
代码:
- public void offer(int val){
- Node node = new Node(val);
- if(head==null){
- head=node;
- last=node;
- }else{
- last.next=node;
- last=node;
- }
- size++;
- }
- public boolean empty(){
- return size==0;
- }
(1)队列为空,则直接返回队列为空的异常。
自定义异常如下:
- public class EmptyException extends RuntimeException{
- public EmptyException(String message) {
- super(message);
- }
- }
(2)队列为空不为,先ret=head.val,后删除头结点head=head.next;,再判断ihead是否为null。
如果是last也要置空。
(3)size--。
代码:
- public int poll(){
- if(isEmpty()){
- throw new EmptyException("栈是空的!");
- }
- int ret=head.val;
- size--;
- head=head.next;
- if(head==null){
- last=null;
- }
- return ret;
- }
代码:
- public int peek(){
- if(empty()){
- throw new EmptyException("队列为空");
- }
- int ret=head.val;
- return ret;
- }
- public class Myqueue {
- class Node{
- public int val;
- public Node next;
- public Node(int val){
- this.val=val;
- }
- }
-
- public Node head;
- public Node last;
- public int size;
-
- public void offer(int val){
- Node node = new Node(val);
- if(head==null){
- head=node;
- last=node;
- }else{
- last.next=node;
- last=node;
- }
- size++;
- }
- public int poll(){
- if(isEmpty()){
- throw new EmptyException("栈是空的!");
- }
- int ret=head.val;
- size--;
- head=head.next;
- if(head==null){
- last=null;
- }
- return ret;
- }
- public boolean empty(){
- return size==0;
- }
- public int peek(){
- if(empty()){
- throw new EmptyException("队列为空");
- }
- int ret=head.val;
- return ret;
- }
- }
- public class MyQueue {
- // 双向链表节点
- public static class ListNode {
- ListNode next;
- ListNode prev;
- int value;
-
- ListNode(int value) {
- this.value = value;
- }
- }
-
- ListNode first; // 队头
- ListNode last; // 队尾
- int size = 0;
-
- // 入队列---向双向链表位置插入新节点
- public void offer(int e) {
- ListNode newNode = new ListNode(e);
- if (first == null) {
- first = newNode;
- // last = newNode;
- } else {
- last.next = newNode;
- newNode.prev = last;
- // last = newNode;
- }
- last = newNode;
- size++;
- }
-
- // 出队列---将双向链表第一个节点删除掉
- public int poll() {
- // 1. 队列为空
- // 2. 队列中只有一个元素----链表中只有一个节点---直接删除
- // 3. 队列中有多个元素---链表中有多个节点----将第一个节点删除
- int value = 0;
- if (first == null) {
- throw new EmptyException("队列为空");
- } else if (first == last) {
- last = null;
- first = null;
- } else {
- value = first.value;
- first = first.next;
- first.prev.next = null;
- first.prev = null;
- }
- --size;
- return value;
- }
-
- // 获取队头元素---获取链表中第一个节点的值域
- public int peek() {
- if (first == null) {
- throw new EmptyException("队列为空");
- }
- return first.value;
- }
- public int size() {
- return size;
- }
- public boolean isEmpty(){
- return first == null;
- }
- }
实际中我们有时还会使用一种队列叫循环队列,环形队列通常使用数组实现。
循环队列
https://leetcode.cn/problems/design-circular-queue/description/描述:


要解决循环队列的有如下几个难题:
(1)数组的下标如何实现循环
rear=(rear+1)%elem.length
front=(front+1)%elem.length
(2)区分空与满
有三个方法:
通过添加 size 属性记录
保留一个位置
使用标记
本博主采用第二个方法,如下图所示:

由于我们需要浪费一个空间来判断是否为满,在构造方法时多构造一个空间。
- class MyCircularQueue {
- private int[] elem;
- private int front;//表示队列的头
- private int rear;//表示队列的尾
-
- public MyCircularQueue(int k) {
- this.elem=new int[k+1];
- }
- }
- public boolean isFull() {
- return (rear+1)%elem.length==front;
- }
- public boolean isEmpty() {
- return rear == front;
- }
(1)判断是否为满,若为满。返回false
(2)若不为满,则在elem下标为rear处插入该元素
(3)队尾向后走一步rear=(rear+1)%elem.length,返回true;
- public boolean enQueue(int value) {
- if(isFull()){
- return false;
- }
- elem[rear]=value;
- rear=(rear+1)%elem.length;
- return true;
- }
判断是否为null
(1)若为null。返回false
(2)若不为null,队首向后走一步 front = (front+1)%elem.length;,返回true;
- public boolean deQueue() {
- if (isEmpty()){
- return false;
- }
- front = (front+1)%elem.length;
- return true;
- }
- public int Front(){
- if(isEmpty()){
- return -1;
- }
- return elem[front];
- }
(1)如果队列为空,返回-1
(2)不为空,如果为队尾下标为0,返回下elem[elem.length-1]的值
(3)下标不为0,返回数组下标为rear-1的值
- public int Rear() {
- if(isEmpty() ) {
- return -1;
- }
- if(rear == 0) {
- return elem[elem.length-1];
- }
- return elem[rear-1];
- }
- class MyCircularQueue {
- private int[] elem;
- private int front;//表示队列的头
- private int rear;//表示队列的尾
-
- public MyCircularQueue(int k) {
- this.elem = new int[k + 1];
- }
-
- public boolean enQueue(int value) {
- if (isFull()) {
- return false;
- }
- elem[rear] = value;
- rear = (rear + 1) % elem.length;
- return true;
- }
-
- public boolean deQueue() {
- if (isEmpty()){
- return false;
- }
- front = (front+1)%elem.length;
- return true;
- }
-
- //从队首获取元素。如果队列为空,返回 -1 。
- public int Front() {
- if(isEmpty() ) {
- return -1;
- }
- return elem[front];
- }
-
-
- //从队尾获取元素。如果队列为空,返回 -1 。
- public int Rear() {
- if(isEmpty() ) {
- return -1;
- }
- if(rear == 0) {
- return elem[elem.length-1];
- }
- return elem[rear-1];
- }
-
-
- //检查循环队列是否为空。
- public boolean isEmpty() {
- return rear == front;
- }
-
-
- public boolean isFull() {
- return (rear + 1) % elem.length == front;
- }
- }
Deque是一个接口,使用时必须创建LinkedList的对象。
在实际工程中,使用Deque接口是比较多的,栈和队列均可以使用该接口
- Deque
stack = new ArrayDeque<>();//双端队列的线性实现 - Deque
queue = new LinkedList<>();//双端队列的链式实现
以上为我个人的小分享,如有问题,欢迎讨论!!!
都看到这了,不如关注一下,给个免费的赞 ![]()
