Cola de algoritmo y estructura de datos JAVA (2)

La semana pasada aprendí sobre las colas en las estructuras y algoritmos de datos JAVA, escribí algo y lo grabé para su revisión posterior, principalmente desde cuatro aspectos: (1) Escenarios de aplicación de cola (2) Introducción detallada de cola (3) Ideas de cola de simulación de matriz Análisis e implementación de código (4) Análisis de la idea de cola circular y resumen de implementación de código (5).

(1) Escenarios de aplicación de colas

       Escenario realista: las colas son muy comunes en la vida diaria, por ejemplo: los bancos hacen fila para los negocios, los comedores hacen fila para las comidas, etc. El banco está haciendo cola para llamar al número, y cuatro empleados atienden a las personas en la cola. Después de que cada empleado complete el servicio, la siguiente persona a ser atendida se generará a partir de la cola siguiente. Las personas en la cola siguen el principio de orden de llegada y esperan a que la ventana las llame una vez para brindar los servicios requeridos. Luego, las personas en la cola equivalen a una cola.

           

Por ejemplo, cuando vamos a una sala de cine para hacer cola para comprar entradas, la primera persona que entra en la cola es la primera persona que compra una entrada y sale de la cola, y la última persona que entra en la cola es la última que compra un boleto.

Por ejemplo, en un sistema operativo de computadora, hay varias colas que funcionan silenciosamente, como una impresora esperando para imprimir en una cola de impresión.

Entonces, ¿cuándo es la cola? ¿Cómo usar Java para implementar la cola?

(2) Introducción detallada de la cola

      Una cola es una lista lineal ordenada, que se puede implementar mediante una matriz o una lista vinculada. Sigue el principio de primero en entrar, primero en salir, es decir, los datos almacenados en la cola primero deben sacarse primero, y los datos almacenados más tarde deben eliminarse más tarde. La diferencia con la pila es que la cola es una estructura que se puede usar en ambos extremos, un extremo se usa para agregar nuevos elementos y el otro extremo elimina elementos, o solo un extremo puede insertar o eliminar datos. El final que realiza la operación de inserción se denomina final de la cola, y el final que realiza la operación de eliminación se denomina cabecera de la cola. Cuando no hay elementos en la cola, se denomina cola vacía.

å¨è¿éæå ¥ å¾çæè¿ °

 La cola se divide en:

  1.   Cola unidireccional (Cola): solo puede insertar datos en un extremo y eliminar datos en el otro extremo.
  2.   Cola bidireccional (Deque): cada extremo puede insertar datos y eliminar operaciones de datos.

En la cola, la cabeza y la cola: el final que permite insertar elementos se llama cola, y el final que permite eliminar elementos se llama cabeza de la cola. Enqueue: insertar operación de cola, sacar de cola: eliminar operación de cola, de la siguiente manera, mostramos la operación push a una cola completa, agregando los números 1, 2, 3, el proceso es el siguiente:

Tome 1, 2, 3 de una cola; la operación de hacer estallar es la siguiente:

 

(3) Análisis de pensamiento y análisis de código de la cola de simulación de matrices

         La cola en sí es una lista ordenada, entonces, ¿cómo usar una matriz para agregar, eliminar, modificar y verificar la cola?

        Si se utiliza la estructura de una matriz para almacenar los datos de la cola, la declaración de la matriz de la cola es como se muestra en la figura siguiente, donde maxSize es la capacidad máxima de la cola. Debido a que la salida y la entrada de la cola se procesan por separado de los extremos frontal y posterior, se requieren dos variables frontal y posterior para registrar los subíndices de los extremos frontal y posterior de la cola respectivamente. El frente cambiará con la salida de datos y la parte trasera cambiará con la entrada de datos, como muestra la imagen:

å¨è¿éæå ¥ å¾çæè¿ °

Cuando almacenamos datos en la cola, se llama "addQueue". El procesamiento de addQueue requiere dos pasos:

El análisis del pensamiento mueve el puntero de cola hacia atrás: trasero + 1, cuando delante == trasero [vacío], si el puntero de cola trasero es menor que el subíndice máximo maxSize-1 de la cola, los datos se almacenarán en el elemento de matriz señalado por detrás, de lo contrario no será posible Guardar los datos. trasero == maxSize-1 [cola llena]; a saber:

  • anverso es la posición antes del elemento delantero de la cola [sin incluir el anverso]
  • trasero es el último elemento de la cola [incluido el último]
  • Inserte la cola, determine si está llena, mueva el puntero de cola hacia atrás: trasero ++, luego inserte arr [trasero]
  • Salga de la cola, determine si está vacía, mueva el puntero frontal hacia atrás: front ++, y luego muévase hacia afuera arr [front]
  • La cola es condición de juicio vacía: cuando delante == detrás 【vacío】
  • La condición para juzgar si la cola está llena: trasero == maxSize-1 [cola llena]

Cuando entendemos la lógica de implementación de la cola, el código de implementación que usa la matriz es:

package JAVADATASTRTUCRE;

import java.util.Scanner;

/**
 * Created with IntelliJ IDEA.
 * User:  yongping Li
 * Date: 2020/11/16
 * Time: 17:06
 * Description: No Description
 */

/*
问题:队列不能重复使用
 */
public class arrayQueueDemo {
    public static void main(String[] args) {
        ArrayQueue arrayQueue = new ArrayQueue(3);
        char key;//接受用户输入
        Scanner scanner =new Scanner(System.in);
        boolean loop=true;
        while(loop){
            System.out.println("s(show):显示队列");
            System.out.println("e(exit):退出程序");
            System.out.println("a(add):添加数据到队列");
            System.out.println("g(get):从队列中取数据");
            System.out.println("h(head):查看队列头部数据");
            key=scanner.next().charAt(0);
            switch (key){
                case 's':
                    arrayQueue.showQueue();
                    break;
                case 'a':
                    System.out.println("请输入一个数");
                    int value=scanner.nextInt();
                    arrayQueue.addQueue(value);
                    break;
                case 'g':
                    try{
                        int res =arrayQueue.getQueue();
                        System.out.println("去除的数据为"+res);
                    }catch(Exception E){
                        System.out.println(E.getMessage());
                    }
                    break;
                case 'h':
                    try{
                        int head =arrayQueue.headQueue();
                        System.out.println("头部的数据为"+head);
                    }catch(Exception E){
                        System.out.println(E.getMessage());
                    }
                    break;
                case 'e':
                    scanner.close();
                    loop=false;
                    break;
                default:
                    break;
            }
        }
        System.out.println("程序退出!!!!");
    }
}

class ArrayQueue{

    private int maxSiaze;//队列的最大容量
    private int front;//队列头部
    private int rear;//队列尾部
    private int []arr;//用于1存放数据,模拟队列

    //创建队列的构造器
    public ArrayQueue(int arrMaxSize){
          maxSiaze=arrMaxSize;
          arr=new int[maxSiaze];
          front=-1;//指向队列头部的前一个位置,
          rear=-1;//指向队列尾部的数据(即队列的最后一个数据)
    }

//判断队列是否满
    public  boolean isFull(){
        return rear==maxSiaze-1;
    }
//判断队列是否为空
    public boolean isEmpty(){
     return rear==front;
    }
//添加数据到队列
public void addQueue(int n){
    //判断队列是否满
    if(isFull()){
        System.out.println("队列已满,");
        return;
    }
      rear++;
      arr[rear]=n;

}
//出队列
public  int getQueue(){
        //判断队列是否为空

    if(isEmpty()){
        //抛出异常
        throw new RuntimeException("队列空,不能取数据");
    }
    front++;
    return arr[front];
}
//显示队列所有数据
public void showQueue(){
 if(isEmpty()){
     System.out.println("队列为空,没有数据");
     return;
 }
   for(int i=0;i<arr.length;i++){
       System.out.printf("arr[%d]=%d\n",i,arr[i]);
   }
}
//显示队列的头数据,并非取数据
public int headQueue(){
        if(isEmpty()){
            //System.out.println("队列为空");
            throw new RuntimeException("队列为空");
        }
        return arr[front+1];
    }
}

Los resultados de la operación son:

 s(show):显示队列
e(exit):退出程序
a(add):添加数据到队列
g(get):从队列中取数据
h(head):查看队列头部数据
s
队列为空,没有数据
s(show):显示队列
e(exit):退出程序
a(add):添加数据到队列
g(get):从队列中取数据
h(head):查看队列头部数据
a
请输入一个数
12
s(show):显示队列
e(exit):退出程序
a(add):添加数据到队列
g(get):从队列中取数据
h(head):查看队列头部数据
a
请输入一个数
23
s(show):显示队列
e(exit):退出程序
a(add):添加数据到队列
g(get):从队列中取数据
h(head):查看队列头部数据
a
请输入一个数
32
s(show):显示队列
e(exit):退出程序
a(add):添加数据到队列
g(get):从队列中取数据
h(head):查看队列头部数据
s
arr[0]=12
arr[1]=23
arr[2]=32
s(show):显示队列
e(exit):退出程序
a(add):添加数据到队列
g(get):从队列中取数据
h(head):查看队列头部数据
g
去除的数据为12
s(show):显示队列
e(exit):退出程序
a(add):添加数据到队列
g(get):从队列中取数据
h(head):查看队列头部数据
h
头部的数据为23
s(show):显示队列
e(exit):退出程序
a(add):添加数据到队列
g(get):从队列中取数据
h(head):查看队列头部数据

Idea de realización dos:

package DataStrtureDemo;

import java.util.LinkedList;

/**
 * Created with IntelliJ IDEA.
 * User:  yongping Li
 * Date: 2020/11/20
 * Time: 8:57
 * Description: No Description
 */
public class arrayQueueDemo {
    public static void main(String[] args) {
        ArrayQueue queue = new ArrayQueue(5);
        queue.printAll();
        System.out.println(queue.isFull());
        //queue.enQueue(6);
        System.out.println(queue.isEmpty());



    }
}

class ArrayQueue{
    private int first,last,size;
    private Object[]  storage;

    public ArrayQueue(){
        this(100);
    }
    public ArrayQueue(int n){
        size=n;
        storage=new Object[size];
        first=last=-1;
    }
    public boolean isFull(){
        return first==0 && last==size-1||first==last+1;
    }
    public boolean isEmpty(){
        return first==-1;
    }
    //队列尾部添加元素
    public void enQueue(Object e){
        if(last==size-1||last==-1){
            storage[0]=e;
            last=0;
            if(first==-1){
                first=0;
            }
        } else{
            storage[++last]=e;
        }
    }
    //从队列中取出元素
    public Object  dequeue(){
        Object tmp=storage[first];
        if(first==last){
            last=first=-1;
        }else if(first==size-1){
            first=0;
        }else {
            first++;
        }
        return tmp;
    }
    public void printAll(){
        for(int i=0;i<size;i++){
            System.out.println(storage[i]+"   ");
        }
    }



}

class  Queue{
    private LinkedList list=new  LinkedList();

    //构造器
    public Queue(){

    }
    public boolean isEmpty(){
        return list.isEmpty();
    }
    //第一个元素
    public Object firstEl(){
        return list.getFirst();
    }
//获取最后一个元素
    public Object  lastEl(){
        return list.getLast();
    }
    public Object dequeue(){
        return list.removeFirst();
    }
    public void enqueue(Object e){
        list.addLast(e);
    }
    public String toString(){
        return list.toString();
    }
}

Los resultados de la operación son:

null   
null   
null   
null   
null   
false
true

Process finished with exit code 0

 

(4) Análisis de pensamiento e implementación de código de cola circular

Razones para usar colas circulares:

(1) En la actualidad, la cola se puede usar una vez y no se puede lograr la reutilización

(2) Diseñe una cola circular y tome el módulo%

 Si el puntero de la cabeza del equipo apuntará a una posición de subíndice más alta, como se muestra a continuación:

  

  Cuando se agregan nuevos datos a la cola, el puntero trasero al final de la cola se moverá hacia arriba, es decir, hacia abajo. Cuando se elimina el elemento de datos, el puntero frontal del encabezado de línea se mueve hacia arriba. Entonces, este diseño parece ser contrario a la realidad, como hacer cola para comprar boletos de cine, el jefe del equipo se irá después de comprar los boletos, y luego el equipo avanzará como un todo. También es posible eliminar un número de la cola en la computadora, y toda la cola avanza, pero esto es muy ineficiente. La forma que elegimos es mover los punteros a la cabeza y la cola del equipo.

 Si mueves el puntero de esta manera, creo que el puntero de cola del equipo pronto se moverá al final de los datos. En este momento, es posible que los datos se hayan eliminado. Entonces habrá una posición vacía al principio de el equipo, y luego aparecerá un nuevo elemento de datos. Subiendo de nuevo, ¿qué debo hacer? Como se muestra abajo:

  

  Para evitar que la cola quede insatisfecha pero no pueda insertar nuevos datos, podemos hacer que el puntero de cola vuelva al principio de la matriz, que también se denomina "cola circular".

  

Eso es como se muestra a continuación:

Consideraciones de implementación de colas circulares:

1. Ajuste el significado de la variable frontal: front apunta al primer elemento de la cola, es decir, arr [front] es el primer elemento de la cola.

2. Ajuste el significado de la variable posterior: posterior apunta al elemento después del último elemento de la cola, porque espera liberar un espacio como una convención (la capacidad real de la cola = maxSize-1, que se entiende que evitar que los errores apunten a lugares más allá del rango de la matriz) .

3. Cuando la cola está llena, la condición es: (trasero + 1)% maxSize == delantero [lleno] 

4. Cuando la cola está vacía, la condición es: trasera == delantera [vacía]

5. El número de datos válidos en la cola: (trasero + maxSize-front)% maxSize

6. Al insertar en la cola, juzgue que la cola está llena, primero inserte en la cola arr [posterior], luego posterior ++

7. Al salir de la cola, juzgue que el equipo está vacío, primero salga de la cola arr [frente], luego al frente ++

En resumen: la idea de diseño de la cola circular es:

El código para la cola circular se implementa como:

package JAVADATASTRTUCRE;

import java.util.Scanner;

/**
 * Created with IntelliJ IDEA.
 * User:  yongping Li
 * Date: 2020/11/16
 * Time: 21:24
 * Description: No Description
 */
public class circleArrayQueueDemo {
    public static void main(String[] args) {
        System.out.println("测试数组环形队列");
        circleArrayQueue arrayQueue = new circleArrayQueue(3);
        char key;//接受用户输入
        Scanner scanner =new Scanner(System.in);
        boolean loop=true;
        while(loop){
            System.out.println("s(show):显示队列");
            System.out.println("e(exit):退出程序");
            System.out.println("a(add):添加数据到队列");
            System.out.println("g(get):从队列中取数据");
            System.out.println("h(head):查看队列头部数据");
            key=scanner.next().charAt(0);
            switch (key){
                case 's':
                    arrayQueue.showQueue();
                    break;
                case 'a':
                    System.out.println("请输入一个数");
                    int value=scanner.nextInt();
                    arrayQueue.addQueue(value);
                    break;
                case 'g':
                    try{
                        int res =arrayQueue.getQueue();
                        System.out.println("去除的数据为"+res);
                    }catch(Exception E){
                        System.out.println(E.getMessage());
                    }
                    break;
                case 'h':
                    try{
                        int head =arrayQueue.headQueue();
                        System.out.println("头部的数据为"+head);
                    }catch(Exception E){
                        System.out.println(E.getMessage());
                    }
                    break;
                case 'e':
                    scanner.close();
                    loop=false;
                    break;
                default:
                    break;
            }
        }
        System.out.println("程序退出!!!!");
    }
}

class circleArrayQueue{

    private int maxSiaze;//队列的最大容量
    private int front;//队列头部,指向队列第一个元素,初始值为0
    private int rear;//队列尾部,指向对列最后一个元素的最后一个位置,初始值为0
    private int []arr;//用于1存放数据,模拟队列

    //创建队列的构造器
    public circleArrayQueue(int arrMaxSize){
        maxSiaze=arrMaxSize;
        arr=new int[maxSiaze];

    }

    //判断队列是否满
    public  boolean isFull(){
        return (rear+1)%maxSiaze==front;
    }
    //判断队列是否为空
    public boolean isEmpty(){
        return rear==front;
    }
    //添加数据到队列
    public void addQueue(int n){
        //判断队列是否满
        if(isFull()){
            System.out.println("队列已满,");
            return;
        }
        arr[rear]=n;
        //将rear后移,取模
        rear=(rear+1) % maxSiaze;

    }
    //出队列,取数据
    public  int getQueue(){
        //判断队列是否为空
        if(isEmpty()){
            //抛出异常
            throw new RuntimeException("队列空,不能取数据");
        }
        //分析front指向队列第一个元素
        //1,front保存到一个临时变量 2.临时保存的变量返回
        //3,front后移,考虑取模
        int value=arr[front];
        front=(front+1)%maxSiaze;
        return value;
    }
    //显示队列所有数据
    public void showQueue(){
        if(isEmpty()){
            System.out.println("队列为空,没有数据");
            return;
        }
        //从front开始便利,遍历多少个元素
        for(int i=0;i<front+getQueueSize();i++){
            System.out.printf("arr[%d]=%d\n",i%maxSiaze,arr[i%maxSiaze]);
        }
    }
    //显示队列的头数据,并非取数据
    public int headQueue(){
        if(isEmpty()){
            //System.out.println("队列为空");
            throw new RuntimeException("队列为空");
        }
        return arr[front];
    }

    //返回当前队列有效数据的个数
    public int getQueueSize(){
        return (rear+maxSiaze-front)%maxSiaze;
    }

}

Los resultados de la operación son:

测试数组环形队列
s(show):显示队列
e(exit):退出程序
a(add):添加数据到队列
g(get):从队列中取数据
h(head):查看队列头部数据
s
队列为空,没有数据
s(show):显示队列
e(exit):退出程序
a(add):添加数据到队列
g(get):从队列中取数据
h(head):查看队列头部数据
a
请输入一个数
12
s(show):显示队列
e(exit):退出程序
a(add):添加数据到队列
g(get):从队列中取数据
h(head):查看队列头部数据
a
请输入一个数
34
s(show):显示队列
e(exit):退出程序
a(add):添加数据到队列
g(get):从队列中取数据
h(head):查看队列头部数据
a
请输入一个数
234
队列已满,
s(show):显示队列
e(exit):退出程序
a(add):添加数据到队列
g(get):从队列中取数据
h(head):查看队列头部数据
s
arr[0]=12
arr[1]=34
s(show):显示队列
e(exit):退出程序
a(add):添加数据到队列
g(get):从队列中取数据
h(head):查看队列头部数据
h
头部的数据为12
s(show):显示队列
e(exit):退出程序
a(add):添加数据到队列
g(get):从队列中取数据
h(head):查看队列头部数据
g
去除的数据为12
s(show):显示队列
e(exit):退出程序
a(add):添加数据到队列
g(get):从队列中取数据
h(head):查看队列头部数据
s
arr[0]=12
arr[1]=34
s(show):显示队列
e(exit):退出程序
a(add):添加数据到队列
g(get):从队列中取数据
h(head):查看队列头部数据
g
去除的数据为34
s(show):显示队列
e(exit):退出程序
a(add):添加数据到队列
g(get):从队列中取数据
h(head):查看队列头部数据
g
队列空,不能取数据
s(show):显示队列
e(exit):退出程序
a(add):添加数据到队列
g(get):从队列中取数据
h(head):查看队列头部数据
a
请输入一个数
1
s(show):显示队列
e(exit):退出程序
a(add):添加数据到队列
g(get):从队列中取数据
h(head):查看队列头部数据
s
arr[0]=12
arr[1]=34
arr[2]=1
s(show):显示队列
e(exit):退出程序
a(add):添加数据到队列
g(get):从队列中取数据
h(head):查看队列头部数据

(5) Resumen

La cola es una tabla lineal que almacena datos de acuerdo con el principio de primero en entrar, primero en salir. Por lo general, se usa para simplificar la estructura de datos de ciertas operaciones del programa, en lugar de principalmente para almacenar datos. Para las colas, la adición, eliminación, modificación y verificación se pueden implementar a través de matrices. El propósito de diseñar listas circulares es el uso repetido de matrices.

 

 

 

 

 

 

 

 

 

Supongo que te gusta

Origin blog.csdn.net/weixin_41792162/article/details/109906039
Recomendado
Clasificación