Cola de matriz escrita a mano en Java y cola de lista vinculada y uso del método de cola listo para usar en Java

ilustrar

Aquí se registra que la función de cola se implementa manualmente utilizando matrices y listas vinculadas, y se utilizan los métodos de cola ya preparados en Java.

Implementar manualmente funciones de cola usando matrices

package com.example.deesign_patterns.test;

//java使用数组简单实现队列
public class ArrayQueue {
    
    
    private int[] queue;  // 内部数组
    private int front;    // 队列头部指针
    private int rear;     // 队列尾部指针
    private int size;     // 队列当前元素个数
    private int capacity; // 队列容量

    //构造方法,初始化的时候必须要传队列容量值
    public ArrayQueue(int capacity) {
    
    
        this.capacity = capacity;
        queue = new int[capacity];
        front = 0;
        rear = -1;
        size = 0;
    }

    //判断是否是空队列
    public boolean isEmpty() {
    
    
        return size == 0;
    }

    //判断队列是否已满
    public boolean isFull() {
    
    
        return size == capacity;
    }

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

    //元素入队列
    public void add(int value) {
    
    
        if (isFull()) {
    
    
            System.out.println("队列已经满了,无法添加队列。");
            return;
        }
        rear = (rear + 1) % capacity; // 循环队列,计算新的尾部位置
        queue[rear] = value;//在数组尾部添加元素
        size++;//如果添加成功,则队列元素数量加1
        System.out.println("入队列元素值: " + value);
    }

    //头部元素出队列,重新计算头部位置,数组索引往后移了一位,相当于删除头元素
    public int pull() {
    
    
        if (isEmpty()) {
    
    
            System.out.println("队列是空的,无法出队列。");
            return -1;
        }
        int value = queue[front];
        front = (front + 1) % capacity; // 循环队列,计算新的头部位置
        size--;//如果出队列成功,则队列元素数量减1
        System.out.println("出队列元素值: " + value);
        return value;
    }

    //获取队列里面的首元素,不会删除元素
    public int peek() {
    
    
        if (isEmpty()) {
    
    
            System.out.println("队列是空的!");
            return -1;
        }
        return queue[front];
    }

    //显示队列元素
    public void display() {
    
    
        if (isEmpty()) {
    
    
            System.out.println("队列是空的!");
            return;
        }
        System.out.print("队列当前元素值: ");
        int index = front;
        for (int i = 0; i < size; i++) {
    
    
            System.out.print(queue[index] + " ");
            index = (index + 1) % capacity; // 循环遍历队列
        }
        System.out.println();
    }

    //测试类
    public static void main(String[] args) {
    
    
        ArrayQueue queue = new ArrayQueue(5);
        queue.add(10);
        queue.add(20);
        queue.add(30);
        queue.display(); // Queue: 10 20 30
        queue.pull();
        queue.display(); // Queue: 20 30
        queue.add(40);
        queue.add(50);
        queue.display(); // Queue: 20 30 40 50
        queue.pull();
        queue.pull();
        queue.display(); // Queue: 40 50
        System.out.println("当前队列首元素为:"+queue.peek());//Queue: 40
    }
}


Los resultados de la ejecución son los siguientes:
Insertar descripción de la imagen aquí

Implemente manualmente la función de cola utilizando una lista vinculada unidireccional

Clase de lista enlazada unidireccional

package com.example.deesign_patterns.test;

//单向链表类
public class Node<T> {
    
    
    public T data;
    public Node next;

    //无参构造方法
    public Node() {
    
    }

    //有参构造方法
    public Node(T data, Node next) {
    
    
        this.data = data;
        this.next = next;
    }

    public T getData() {
    
    
        return data;
    }

    public void setData(T data) {
    
    
        this.data = data;
    }

    public Node getNext() {
    
    
        return next;
    }

    public void setNext(Node next) {
    
    
        this.next = next;
    }
}

La interfaz funcional que la cola debe implementar (también puede escribir métodos directamente en la clase de cola de la lista vinculada):

package com.example.deesign_patterns.test;

/**
 * 队列功能接口
 * 队列是一种先进先出的线性表
 * 只能在表的一端进行插入,另一段进行删除
 * 允许插入的一端叫队尾,允许删除的一端叫队头()
 */
public interface IQueue<T> {
    
    
    /**
     * 初始化队列 构造一个空队列
     */
    IQueue InitQueue();

    /**
     * 销毁队列
     */
    IQueue DestroyQueue();

    /**
     * 清空队列
     */
    IQueue ClearQueue();

    /**
     * 队列判空
     */
    Boolean isEmpty();

    /**
     * 返回队列长度
     */
    Integer QueueLength();

    /**
     * 返回队列头元素
     */
    T GetHead();

    /**
     * 插入队尾元素
     */
    Boolean EnQueue(T e);

    /**
     * 删除队头元素  即出队
     */
    T DeQueue();

    /**
     * 打印队列元素
     */
    void printQueue();
}

Clase de cola de lista vinculada:

package com.example.deesign_patterns.test;

//java使用链表简单实现队列
public class LinkedQueue<T> implements IQueue<T> {
    
    
    private  Node<T> front;//队头指针
    private  Node<T> rear;//队尾指针
    private int size;//队列长度

    //无参构造方法
    public LinkedQueue() {
    
    
        front = null;
        rear = null;
        size = 0;
    }

    //初始化队列方法
    @Override
    public IQueue InitQueue() {
    
    
        front = null;
        rear = null;
        size = 0;
        return this;
    }

    //销毁队列方法
    @Override
    public IQueue DestroyQueue() {
    
    
        //销毁
        front = null;
        rear = null;
        size = 0;
        return this;
    }

    //清空队列方法
    @Override
    public IQueue ClearQueue() {
    
    
        front = null;
        rear = null;
        size = 0;
        return this;
    }

    //判断队列是否为空
    @Override
    public Boolean isEmpty() {
    
    
        return size == 0;
    }

    //判断队列长度
    @Override
    public Integer QueueLength() {
    
    
        return size;
    }

    //获取队列里面的首元素
    @Override
    public T GetHead() {
    
    
        if (isEmpty()) {
    
    
            return null;
        }
        return front.getData();
    }

    //将元素入队
    @Override
    public Boolean EnQueue(T e) {
    
    
        Node<T> newNode = new Node<>(e, null);
        if (isEmpty()) {
    
    
            front = newNode;
        } else {
    
    
            rear.setNext(newNode);
        }
        rear = newNode;
        size++;
        return true;
    }

    //将元素出队
    @Override
    public T DeQueue() {
    
    
        if (isEmpty()) {
    
    
            return null;
        }
        T data = front.getData();
        front = front.getNext();
        size--;
        if (isEmpty()) {
    
    
            rear = null;
        }
        return data;
    }

    @Override
    public void printQueue() {
    
    
        for (Node current = front;current != null;current = current.next){
    
    
            System.out.print(current.data+" ");
        }
        System.out.println();
    }
	
	//测试类
    public static void main(String[] args) {
    
    
        IQueue<Integer> queue = new LinkedQueue<>();
        queue.InitQueue();
        queue.EnQueue(1);
        queue.EnQueue(2);
        queue.EnQueue(3);
        System.out.println("队列长度: " + queue.QueueLength());
        queue.printQueue();//打印队列值
        System.out.println("队头元素: " + queue.GetHead());
        System.out.println("出队元素: " + queue.DeQueue());
        System.out.println("出队元素: " + queue.DeQueue());
        System.out.println("出队元素: " + queue.DeQueue());
        queue.printQueue();//打印队列值
        System.out.println("队列长度: " + queue.QueueLength());
        System.out.println("队列是否为空: " + queue.isEmpty());
    }
}

Insertar descripción de la imagen aquí

Uso de ArrayBlockingQueue, ArrayQueue y LinkedBlockingQueue en Java

En Java, ArrayBlockingQueue y ArrayQueue son dos implementaciones de cola diferentes. Entre ellos existen las siguientes diferencias:

  1. La estructura de datos es diferente: ArrayBlockingQueue es una cola de bloqueo limitada basada en matrices y su capacidad es fija. ArrayQueue es una cola ilimitada basada en matrices y su capacidad puede crecer dinámicamente.
  2. La diferencia entre operaciones de inserción y eliminación: las operaciones de inserción y eliminación de ArrayBlockingQueue son seguras para subprocesos y admiten operaciones de bloqueo. Cuando la cola está llena, la operación de inserción se bloqueará hasta que haya espacio disponible; cuando la cola esté vacía, la operación de eliminación se bloqueará hasta que haya un elemento disponible. Las operaciones de inserción y eliminación de ArrayQueue no son seguras para subprocesos y deben manejar la sincronización por sí mismas.
  3. Diferencias de rendimiento: debido a que ArrayBlockingQueue admite operaciones de bloqueo, tiene una mejor seguridad de subprocesos en un entorno de subprocesos múltiples. Sin embargo, su rendimiento es relativamente bajo debido a la necesidad de lidiar con la sincronización y el bloqueo. Por el contrario, ArrayQueue funciona mejor en un entorno de un solo subproceso y no necesita lidiar con sincronización ni bloqueo.

ArrayQueue se utiliza de la siguiente manera:

package com.example.deesign_patterns.test;

import com.sun.jmx.remote.internal.ArrayQueue;

public class Test3Main {
    
    

    public static void main(String[] args) {
    
    
        //数组队列使用,给数组一个大小,当数组里面的元素数量超过5,就会报错,可以通过resize()方法扩容
        ArrayQueue arrayQueue=new ArrayQueue<Integer>(5);
        arrayQueue.add(1);//入队列
        arrayQueue.add(2);
        arrayQueue.add(3);
        arrayQueue.add(4);
        arrayQueue.add(5);
        System.out.println("当前队列元素:"+arrayQueue);
        System.out.println("当前队列大小:"+arrayQueue.size());
        System.out.println("获取当前队列索引为1的元素:"+arrayQueue.get(1));
        //重新设置队列大小,相当于扩容,扩容后大小由原来的5变为6,值必须比原来大
        arrayQueue.resize(6);
        arrayQueue.add(6);
        System.out.println("当前队列元素:"+arrayQueue);
        System.out.println("当前队列大小:"+arrayQueue.size());
        //只能删除队列头元素,必须是索引0,不为0报错,相当于出队列
        arrayQueue.remove(0);
        System.out.println("当前队列元素:"+arrayQueue);
    }
}

Insertar descripción de la imagen aquí

Los métodos comúnmente utilizados de ArrayBlockingQueue son los siguientes:

En Java, ArrayBlockingQueue es una cola de bloqueo con capacidad fija. Su implementación se basa en matrices, implementa la interfaz BlockingQueue y proporciona un conjunto de métodos para operar elementos en la cola.

  1. agregar (elemento): agrega un elemento al final de la cola. Si la cola está llena, se produce una excepción IllegalStateException.
  2. oferta (elemento): agrega un elemento al final de la cola; si la cola está llena, devuelve falso.
  3. put (elemento): agrega un elemento al final de la cola. Si la cola está llena, se bloqueará hasta que haya un espacio libre en la cola.
  4. poll(): elimina y devuelve un elemento del encabezado de la cola, o nulo si la cola está vacía.
  5. take(): elimina y devuelve un elemento del encabezado de la cola. Si la cola está vacía, se bloqueará hasta que un elemento esté disponible en la cola.
  6. peek(): Obtiene el elemento al principio de la cola, pero no lo elimina.
  7. size(): Devuelve el número de elementos actuales en la cola.
  8. restanteCapacity(): Devuelve la capacidad disponible restante en la cola.
  9. isEmpty (): determina si la cola está vacía, si la cola está vacía, devuelve verdadero, de lo contrario devuelve falso.
package com.example.deesign_patterns.test;

import java.util.concurrent.ArrayBlockingQueue;

public class Test3Main {
    
    

    public static void main(String[] args) {
    
    
        //数组队列使用,必须给数组一个大小,当数组里面的元素数量超过5,就会报错,不能扩容
        ArrayBlockingQueue queue=new ArrayBlockingQueue(5);
        queue.add(1);
        queue.add(2);
        queue.add(3);
        queue.add(4);
        queue.add(5);
        System.out.println("当前队列元素:"+queue);
        System.out.println("当前队列大小:"+queue.size());
        System.out.println("队列已满返回boolean值为:"+queue.offer(6));
        System.out.println("获取队列头部元素:"+queue.peek());
        //出队列
        queue.poll();
        System.out.println("当前队列元素:"+queue);
        System.out.println("当前队列可用容量:"+ queue.remainingCapacity());
    }
}


Insertar descripción de la imagen aquí

Los métodos comúnmente utilizados de LinkedBlockingQueue son los siguientes:

LinkedBlockingQueue es una cola segura para subprocesos cuya implementación se basa en una lista vinculada. La capacidad de LinkedBlockingQueue puede ser ilimitada.

Los métodos más utilizados son los mismos que el método de cola ArrayBlockingQueue.

package com.example.deesign_patterns.test;

import java.util.concurrent.LinkedBlockingQueue;

public class Test3Main {
    
    

    public static void main(String[] args) {
    
    
        //链表队列使用
        //如果没有给链表一个大小,默认值是Integer.MAX_VALUE
        //LinkedBlockingQueue queue=new LinkedBlockingQueue();
        //如果给链表一个大小,当链表里面的元素数量超过5,就会报错,不能扩容
        LinkedBlockingQueue queue=new LinkedBlockingQueue(5);
        queue.add(1);
        queue.add(2);
        queue.add(3);
        queue.add(4);
        queue.add(5);
        System.out.println("当前队列元素:"+queue);
        System.out.println("当前队列大小:"+queue.size());
        System.out.println("队列已满返回boolean值为:"+queue.offer(6));
        System.out.println("获取队列头部元素:"+queue.peek());
        //出队列
        queue.poll();
        System.out.println("当前队列元素:"+queue);
        System.out.println("当前队列可用容量:"+ queue.remainingCapacity());
    }
}

Insertar descripción de la imagen aquí

La diferencia entre ArrayBlockingQueue y LinkedBlockingQueue

ArrayBlockingQueue y LinkedBlockingQueue en Java implementan la interfaz BlockingQueue y se utilizan para implementar colas de bloqueo en entornos multiproceso. Las diferencias entre ellos incluyen principalmente los siguientes aspectos:

  1. Estructura de datos: ArrayBlockingQueue usa matrices como estructura de datos subyacente, mientras que LinkedBlockingQueue usa listas vinculadas como estructura de datos subyacente. Esto da como resultado diferentes características de rendimiento para las operaciones de inserción y eliminación.
  2. Tamaño de la cola: ArrayBlockingQueue tiene una capacidad fija y debe especificarse al crear, mientras que la capacidad de LinkedBlockingQueue es opcional y su valor predeterminado es Integer.MAX_VALUE.
  3. Bloqueo de subprocesos: cuando ArrayBlockingQueue inserta y elimina elementos, si la cola está llena o vacía, el subproceso de operación se bloqueará hasta que haya espacio o elementos disponibles para la operación. Cuando LinkedBlockingQueue inserta y elimina elementos, si la cola está llena o vacía, el hilo de operación puede optar por bloquearse o regresar inmediatamente.
  4. Rendimiento de iteración: debido a que LinkedBlockingQueue utiliza una lista vinculada como estructura de datos subyacente, el rendimiento de las operaciones de iteración suele ser mejor que ArrayBlockingQueue.
  5. Rendimiento: en escenarios de alta concurrencia, LinkedBlockingQueue generalmente tiene un mejor rendimiento que ArrayBlockingQueue porque puede admitir mejor operaciones simultáneas de inserción y eliminación.

En resumen, ArrayBlockingQueue es adecuado para escenarios con requisitos de capacidad fijos y el subproceso de operación debe bloquearse cuando la cola está llena o vacía, mientras que LinkedBlockingQueue es adecuado para escenarios sin requisitos de capacidad fijos y puede admitir mejor la inserción y operaciones de borrado. .

Supongo que te gusta

Origin blog.csdn.net/weixin_48040732/article/details/132693211
Recomendado
Clasificación