[Java] Principio y estructura de datos gráficos en Java

Inserte la descripción de la imagen aquí
Original: http://www.javastack.cn/article/2018/data-structure-and-the-principle-diagram/

Recientemente, para organizar el conocimiento de la estructura de datos, miré sistemáticamente las estructuras de datos de uso común en Java, y de repente quise usar la animación para dibujar el proceso de flujo de datos.

Basado principalmente en jdk8, puede haber algunas características diferentes de antes de jdk7, por ejemplo, la lista bidireccional en LinkedList LinkedHashMap ya no es loopback.

La lista de enlaces individuales en HashMap se inserta al final, no al principio, etc., y estas diferencias no se repetirán en el siguiente texto. La estructura de directorios de este artículo es la siguiente:

Inserte la descripción de la imagen aquí

Lista enlazada

La clásica estructura de lista de doble enlace es adecuada para la inserción y eliminación fuera de orden. El rendimiento de las operaciones de secuencia especificadas no es tan bueno como ArrayList, que también está determinado por su estructura de datos.

agregar (E) / agregarLast (E)

Inserte la descripción de la imagen aquí

agregar (índice, E)

Aquí hay una pequeña optimización. Primero determinará si el índice está cerca de la cabeza o del final del equipo para determinar en qué dirección atravesar la cadena.

1         if (index < (size >> 1)) {
    
    
2             Node<E> x = first;
3             for (int i = 0; i < index; i++)
4                 x = x.next;
5             return x;
6         } else {
    
    
7             Node<E> x = last;
8             for (int i = size - 1; i > index; i--)
9                 x = x.prev;
10             return x;
11         }

Inserte la descripción de la imagen aquí

Cerca del final
Inserte la descripción de la imagen aquí

obtener (índice)

También juzgará el índice primero, pero el rendimiento aún no es bueno, por lo que no se recomienda usar for (int i = 0; i <lengh; i ++) para atravesar la lista enlazada, sino usar iterador para atravesar.

Inserte la descripción de la imagen aquí

Inserte la descripción de la imagen aquí

eliminar (E)

Inserte la descripción de la imagen aquí

La
capa inferior de ArrayList es una matriz, por lo que buscar en orden es rápido, insertar fuera de orden y eliminar porque implica mover los elementos detrás, por lo que el rendimiento es lento.

agregar (índice, E)

Inserte la descripción de la imagen aquí

Expansión

Generalmente, la capacidad predeterminada es 10, después de la expansión, será de longitud * 1,5.

Inserte la descripción de la imagen aquí

eliminar (E)

Recorra la matriz para determinar si E es igual al elemento actual y el rendimiento de eliminación no es tan bueno como LinkedList.

Inserte la descripción de la imagen aquí

La
estructura de datos clásica de Stack , la capa inferior también es una matriz, heredada de Vector, FILO primero en entrar y último en salir, la nueva capacidad predeterminada de Stack () es 10, que supera la expansión automática.

empujar (E)
Inserte la descripción de la imagen aquí

popular()

Inserte la descripción de la imagen aquí


Una aplicación típica de la expresión de sufijo Stack es calcular la expresión como 9 + (3-1) * 3 + 10/2, la computadora convierte la expresión de infijo en la expresión de sufijo y luego calcula la expresión de sufijo. Lectura recomendada: 8 preguntas de la entrevista de estructura de datos que los programadores de Java deben dominar, ¿cuántas sabrá?

Infijo a sufijo

Salida directa digital

Cuando la pila está vacía, se encuentra un operador y la pila se empuja directamente

Encuentra un paréntesis izquierdo, ponlo en la pila

Cuando se encuentra el paréntesis derecho, se realiza la operación emergente y los elementos emergentes se generan hasta que el paréntesis izquierdo se extrae de la pila y el paréntesis izquierdo no se muestra.

Se encontró con un operador (suma, resta, multiplicación y división): saque todos los elementos superiores de la pila cuya prioridad sea mayor o igual que la del operador, y luego empuje al operador hacia la pila

Finalmente, los elementos de la pila se extraen y generan secuencialmente.

Inserte la descripción de la imagen aquí

Calcular expresión de sufijo

Cuando encuentre un número, empuje el número en la pila

Cuando se encuentre con un operador, coloque los dos números en la parte superior de la pila, use el operador para hacer los cálculos correspondientes en ellos y empuje el resultado a la pila

Repita el proceso anterior hasta el extremo derecho de la expresión

El valor obtenido por la operación es el resultado de la expresión
Inserte la descripción de la imagen aquí


La diferencia entre Queue y Stack es que la eliminación y la adición de Stack se realizan al final de la cola, mientras que la eliminación de Queue está al principio de la cola y la adición al final de la cola.

ArrayBlockingQueue

Una cola delimitada por bloqueo que se usa comúnmente en los consumidores de producción, FIFO.

poner (E)
Inserte la descripción de la imagen aquí

put (E) La cola está llena

1 bloqueo ReentrantLock final = this.lock;
2 lock.lockInterruptiblemente ();
3 prueba { 4 while (count == items.length) 5 notFull.await (); 6 poner en cola (e); 7} finalmente { 8 lock.unlock (); 9}






Inserte la descripción de la imagen aquí

tomar()

Cuando se saca el elemento, no desplaza los elementos detrás de la matriz, sino que actualiza takeIndex para que apunte al siguiente elemento.

takeIndex es un crecimiento circular, cuando se mueve al final de la cola, apuntará a 0 y volverá a hacer un bucle.

1 privado E dequeue () { 2 // afirmar lock.getHoldCount () == 1; 3 // afirmar elementos [takeIndex]! = Null; 4 objetos finales [] elementos = this.items; 5 @SuppressWarnings ("sin marcar") 6 E x = (E) elementos [takeIndex]; 7 elementos [takeIndex] = nulo; 8 if (++ takeIndex == items.length) 9 takeIndex = 0; 10 cuentas–; 11 if (itrs! = Null ) 12 itrs.elementDequeued (); 13 notFull.signal (); 14 return x; 15 }













Inserte la descripción de la imagen aquí

HashMap es la
tabla hash más utilizada, conocimiento necesario para los zapatos de los niños para entrevistas. Se implementa internamente mediante array + lista enlazada individualmente. Se introducen árboles rojo-negro en jdk8 para optimizar listas enlazadas con una longitud> 8. Hablaremos de ello en otro espacio. Lectura recomendada: 8 preguntas de la entrevista de estructura de datos que los programadores de Java deben dominar, ¿cuántas sabrá?

poner (K, V **) **

Inserte la descripción de la imagen aquí

poner (K, V) el mismo valor hash
Inserte la descripción de la imagen aquí

Cambiar el tamaño de la expansión dinámica

Cuando los elementos del mapa superen el umbral establecido, se llevará a cabo la operación de cambio de tamaño (longitud * 2) Durante el proceso de expansión, los elementos serán operados y colocados en una nueva posición. Lectura recomendada: 8 preguntas de entrevista sobre estructura de datos que los programadores de Java deben dominar, ¿cuántas sabrá?

Las operaciones específicas son las siguientes:

Refresque todos los elementos directamente en jdk7 y colóquelos en nuevas ubicaciones.

En jdk8, juzgue si el bit recién agregado del valor hash original del elemento es 0 o 1, 0 significa que el índice permanece sin cambios, 1 significa que el índice se convierte en "índice original + oldTable.length".

1 // Definir dos cadenas
2 // El valor hash original de la cadena recién agregada con bit 0, cabeza y cola
3 Node <K, V> loHead = null, loTail = null;
4 // El valor hash original es nuevo La cadena con el bit aumentado de 1, cabeza y cola
5 Node <K, V> hiHead = null, hiTail = null;
6 Node <K, V> next;
7 // Bucle a través de la cadena
8 do { 9 next = e.next; 10 if ((e.hash & oldCap) == 0) { 11 if (loTail == null) 12 loHead = e; 13 else 14 loTail.next = e; 15 loTail = e; 16} 17 else { 18 if (hiTail == null) 19 hiHead = e; 20 else 21 hiTail.next = e; 22 hiTail = e; 23} 24} while ((e = next)! = Null); 25 // Posición antes y después de la expansión La cadena inmutable 26 if (loTail! = Null) {


















27 loTail.next = null;
28 newTab [j] = loHead;
29}
30 // La posición expandida más la longitud del arreglo original
31 if (hiTail! = Null) { 32 hiTail.next = null; 33 newTab [j + oldCap] = hiHead; 34}



Inserte la descripción de la imagen aquí

LinkedHashMap
hereda de HashMap, y la capa inferior mantiene además una lista doblemente vinculada para mantener el orden de los datos. El almacenamiento en caché FIFO (orden de inserción) o LRU (orden de acceso) se puede lograr configurando accessOrder.

poner (K, V)

Inserte la descripción de la imagen aquí

obtener (K)

Cuando accessOrder es falso, simplemente devuelva el elemento directamente sin ajustar la posición.

Cuando accessOrder es verdadero, el elemento al que se accedió más recientemente debe colocarse al final de la cola.

Inserte la descripción de la imagen aquí

removeEldestEntry elimina el elemento más antiguo

Inserte la descripción de la imagen aquí

(Terminar)

Supongo que te gusta

Origin blog.csdn.net/qq_21383435/article/details/108511678
Recomendado
Clasificación