Matriz versus lista vinculada

200

¿Por qué alguien querría usar una lista vinculada en una matriz?

Codificar una lista vinculada es, sin duda, un poco más trabajo que usar una matriz y uno puede preguntarse qué justificaría el esfuerzo adicional.

Creo que la inserción de nuevos elementos es trivial en una lista vinculada, pero es una tarea importante en una matriz. ¿Existen otras ventajas de usar una lista vinculada para almacenar un conjunto de datos en lugar de almacenarlos en una matriz?

Esta pregunta no es un duplicado de esta pregunta porque la otra pregunta es específicamente sobre una clase de Java en particular, mientras que esta pregunta se refiere a las estructuras de datos generales.

Onorio Catenacci
fuente
1
Relacionado: ¿ cuándo usar LinkedList <> sobre ArrayList <>? - es Java, pero las matrices (ArrayList) y las listas vinculadas presumiblemente tienen el mismo rendimiento en cualquier idioma.
Bernhard Barker
1
@rootTraveller En realidad, esa pregunta sería un duplicado de esta pregunta porque mi pregunta se publicó primero.
Onorio Catenacci

Respuestas:

147
  • Es más fácil almacenar datos de diferentes tamaños en una lista vinculada. Una matriz supone que cada elemento tiene exactamente el mismo tamaño.
  • Como mencionó, es más fácil que una lista vinculada crezca orgánicamente. El tamaño de una matriz debe conocerse con anticipación o volver a crearse cuando necesita crecer.
  • Mezclar una lista vinculada es solo cuestión de cambiar qué puntos a qué. Mezclar una matriz es más complicado y / o requiere más memoria.
  • Mientras sus iteraciones sucedan en un contexto "foreach", no perderá ningún rendimiento en la iteración.
Ryan
fuente
19
¿Cómo se tratan los artículos de diferentes tamaños de manera diferente? Una lista vinculada utiliza una estructura fija con un campo siguiente (requiere un tamaño fijo) o almacena un puntero a los datos en el automóvil (tamaño variable correcto). Ambos enfoques son igual de fáciles con un vector. Lo mismo para barajar.
Brian
32
Yo diría que barajar una matriz es menos complicado.
Hugh Allen
23
Esta respuesta es incorrecta y engañosa. (excepto por la necesidad de saber el tamaño de una matriz cuando la declaras)
Robert Paulson
35
¿No sería más lento iterar una lista vinculada debido a la localidad de los datos?
Firas Assaad
66
@Rick, los vectores suelen sobreasignar el espacio que requieren para que no necesiten asignar nuevo espacio cada vez que aumenta el tamaño. El resultado es que los vectores suelen ser mucho menos intensivos en memoria, no más que las listas vinculadas.
Winston Ewert
179

Otra buena razón es que las listas enlazadas se prestan muy bien para implementaciones eficientes de subprocesos múltiples. La razón de esto es que los cambios tienden a ser locales, afectando solo un puntero o dos para insertar y eliminar en una parte localizada de la estructura de datos. Por lo tanto, puede tener muchos hilos trabajando en la misma lista vinculada. Aún más, es posible crear versiones sin bloqueo utilizando operaciones de tipo CAS y evitar por completo los bloqueos pesados.

Con una lista vinculada, los iteradores también pueden atravesar la lista mientras se producen modificaciones. En el caso optimista donde las modificaciones no chocan, los iteradores pueden continuar sin contención.

Con una matriz, es probable que cualquier cambio que modifique el tamaño de la matriz requiera bloquear una gran parte de la matriz y, de hecho, es raro que esto se haga sin un bloqueo global en toda la matriz para que las modificaciones se conviertan en un obstáculo para los asuntos mundiales.

Alex Miller
fuente
9
Alex: esa es una consideración interesante que nunca se me habría ocurrido. Muy buena respuesta. Te votaría dos veces si pudiera. :-)
Onorio Catenacci
55
Eche un vistazo a las listas de omisión (en particular, ConcurrentSkipListMap en Java 6) para tener una buena idea de dónde puede ir con esto. CSLM es un mapa ordenado y concurrente con excelente rendimiento. Mucho, mucho mejor que un TreeMap sincronizado. tech.puredanger.com/2007/10/03/skip-lists
Alex Miller
... excepto eso ConcurrentSkipListMapo ConcurrentSkipListMapno son listas, incluso si "Lista" aparece en algún lugar de su nombre. Ambos requieren claves que serán ordenadas y únicas. Si necesita una List, es decir, esa estructura de datos que permite elementos duplicados en un orden arbitrario, eso no es adecuado y tendría que hacer grandes esfuerzos para hacer una estructura de datos como LinkedListuna cosa actualizable al mismo tiempo. Si solo necesita una cola o deque concurrente, bueno, sí, incluso hay ejemplos existentes, pero concurrentes List... No estoy convencido de que esto sea posible.
Holger
128

Wikipedia tiene muy buena sección sobre las diferencias.

Las listas enlazadas tienen varias ventajas sobre las matrices. Los elementos se pueden insertar en listas vinculadas de forma indefinida, mientras que una matriz eventualmente se llenará o necesitará redimensionarse, una operación costosa que incluso podría no ser posible si la memoria está fragmentada. Del mismo modo, una matriz de la que se eliminan muchos elementos puede volverse un desperdicio vacío o debe hacerse más pequeña.

Por otro lado, las matrices permiten el acceso aleatorio, mientras que las listas vinculadas solo permiten el acceso secuencial a los elementos. Las listas enlazadas individualmente, de hecho, solo se pueden recorrer en una dirección. Esto hace que las listas vinculadas no sean adecuadas para aplicaciones en las que es útil buscar rápidamente un elemento por su índice, como el montón. El acceso secuencial en las matrices también es más rápido que en las listas vinculadas en muchas máquinas debido a la localidad de referencia y los cachés de datos. Las listas vinculadas casi no reciben ningún beneficio del caché.

Otra desventaja de las listas vinculadas es el almacenamiento adicional necesario para las referencias, lo que a menudo las hace poco prácticas para listas de elementos de datos pequeños, como caracteres o valores booleanos. También puede ser lento, y con un asignador ingenuo, derrochador, para asignar memoria por separado para cada elemento nuevo, un problema generalmente resuelto usando grupos de memoria.

http://en.wikipedia.org/wiki/Linked_list

Jonas Klemming
fuente
44
Esta es la respuesta perfecta. Describe sucintamente las ventajas y desventajas de ambos.
Rick
gracias)) muy simple pero no lo he visto en wiki)
Timur Fayzrakhmanov
58

Agregaré otro: las listas pueden actuar como estructuras de datos puramente funcionales .

Por ejemplo, puede tener listas completamente diferentes que comparten la misma sección final

a = (1 2 3 4, ....)
b = (4 3 2 1 1 2 3 4 ...)
c = (3 4 ...)

es decir:

b = 4 -> 3 -> 2 -> 1 -> a
c = a.next.next  

sin tener que copiar los datos señalados por aen by c.

Es por eso que son tan populares en lenguajes funcionales, que usan variables inmutables, prependy las tailoperaciones pueden ocurrir libremente sin tener que copiar los datos originales, características muy importantes cuando se trata los datos como inmutables.

Brian
fuente
44
Sin embargo, otra consideración muy interesante que nunca habría tenido. Gracias.
Onorio Catenacci
¿Cómo puedo hacer esto en Python?
intercambio excesivo el
29

Además de insertar en el medio de la lista, es más fácil: también es mucho más fácil eliminar del medio de una lista vinculada que una matriz.

Pero, francamente, nunca he usado una lista vinculada. Cada vez que necesitaba una inserción y eliminación rápidas, también necesitaba una búsqueda rápida, así que fui a un HashSet o un Diccionario.

Tom Ritter
fuente
2
Muy cierto, la inserción y eliminación se produce después de la búsqueda la mayor parte del tiempo, por lo que también debe considerar la suma de las complejidades del tiempo.
MA Hossain Tonu
28

Fusionar dos listas vinculadas (especialmente dos listas doblemente vinculadas) es mucho más rápido que fusionar dos matrices (suponiendo que la fusión sea destructiva). El primero toma O (1), el segundo toma O (n).

EDITAR: Para aclarar, quise decir "fusionar" aquí en el sentido desordenado, no como en el tipo de fusión. Quizás "concatenar" hubiera sido una mejor palabra.

rampion
fuente
2
Solo si simplemente está agregando una lista a la otra. Si realmente está fusionando dos listas ordenadas, se necesitará un registro más que O (1).
Herms
3
@Herms, pero puede fusionar dos listas vinculadas ordenadas sin asignar memoria adicional, solo recorriendo ambas listas y configurando los punteros adecuadamente. La fusión de dos matrices normalmente requeriría al menos una matriz adicional.
Paul Tomblin el
1
Sí, fusionar listas es más eficiente en memoria, pero eso no fue realmente lo que estaba comentando. Decir que fusionar listas vinculadas es O (1) es muy engañoso sin aclarar el caso.
Herms
Las listas de fusión de @Herms no son más eficientes en memoria que la fusión de matrices en cualquier modelo de datos sensibles.
Alexei Averchenko
2
Alexei Averchenko: la concatenación de dos listas, o incluso la clasificación de fusión de dos listas ordenadas, se puede hacer en su lugar, con memoria O (1). La concatenación de dos matrices requiere necesariamente O (n) de memoria, a menos que las matrices ya estén adyacentes en la memoria. Creo que el punto al que apunta es que una lista de n elementos y una matriz de n elementos toman memoria O (n), pero el coeficiente es mayor para las listas vinculadas.
rampion
17

Un argumento muy poco apreciado para ArrayList y en contra de LinkedList es que los LinkedLists son incómodos durante la depuración . El tiempo dedicado por los desarrolladores de mantenimiento para comprender el programa, por ejemplo, para encontrar errores, aumenta y, en mi humilde opinión, a veces no justifica los nanosegundos en las mejoras de rendimiento o los bytes en el consumo de memoria en aplicaciones empresariales. A veces (bueno, por supuesto, depende del tipo de aplicaciones), es mejor desperdiciar algunos bytes pero tener una aplicación que sea más fácil de mantener o de entender.

Por ejemplo, en un entorno Java y usando el depurador Eclipse, depurar una ArrayList revelará una estructura muy fácil de entender:

arrayList   ArrayList<String>
  elementData   Object[]
    [0] Object  "Foo"
    [1] Object  "Foo"
    [2] Object  "Foo"
    [3] Object  "Foo"
    [4] Object  "Foo"
    ...

Por otro lado, ver el contenido de LinkedList y encontrar objetos específicos se convierte en una pesadilla de hacer clic en Expandir el árbol, sin mencionar la sobrecarga cognitiva necesaria para filtrar las partes internas de LinkedList:

linkedList  LinkedList<String>
    header  LinkedList$Entry<E>
        element E
        next    LinkedList$Entry<E>
            element E   "Foo"
            next    LinkedList$Entry<E>
                element E   "Foo"
                next    LinkedList$Entry<E>
                    element E   "Foo"
                    next    LinkedList$Entry<E>
                    previous    LinkedList$Entry<E>
                    ...
                previous    LinkedList$Entry<E>
            previous    LinkedList$Entry<E>
        previous    LinkedList$Entry<E>
mhaller
fuente
17

En primer lugar, en las listas enlazadas de C ++ no debería haber muchos más problemas para trabajar que una matriz. Puede usar std :: list o la lista de punteros de impulso para las listas vinculadas. Los problemas clave con las listas vinculadas frente a las matrices son el espacio adicional requerido para los punteros y el terrible acceso aleatorio. Debe usar una lista vinculada si

  • no necesita acceso aleatorio a los datos
  • agregará / eliminará elementos, especialmente en el medio de la lista
David Nehme
fuente
14

Para mi es así,

  1. Acceso

    • Las listas enlazadas solo permiten el acceso secuencial a los elementos. Por lo tanto, la complejidad algorítmica es el orden de O (n)
    • Las matrices permiten el acceso aleatorio a sus elementos y, por lo tanto, la complejidad es el orden de O (1)
  2. Almacenamiento

    • Las listas vinculadas requieren un almacenamiento adicional para las referencias. Esto los hace poco prácticos para listas de elementos de datos pequeños como caracteres o valores booleanos.
    • Las matrices no necesitan un almacenamiento adicional para apuntar al siguiente elemento de datos. Se puede acceder a cada elemento a través de índices.
  3. Talla

    • El tamaño de las listas vinculadas es dinámico por naturaleza.
    • El tamaño de la matriz está restringido a la declaración.
  4. Inserción / Eliminación

    • Los elementos se pueden insertar y eliminar en listas vinculadas indefinidamente.
    • La inserción / eliminación de valores en matrices es muy costosa. Requiere reasignación de memoria.
Sulman
fuente
Tienes 2 número 2 y 2 número 3 :)
Hengameh
Podemos declarar una matriz vacía y luego seguir agregando datos como se requiere. ¿Cómo hace todavía un tamaño fijo?
HebleV
11

Dos cosas:

Codificar una lista vinculada es, sin duda, un poco más trabajo que usar una matriz y se preguntó qué justificaría el esfuerzo adicional.

Nunca codifique una lista vinculada cuando use C ++. Solo usa el STL. Lo difícil que es implementar nunca debería ser una razón para elegir una estructura de datos sobre otra porque la mayoría ya están implementadas.

En cuanto a las diferencias reales entre una matriz y una lista vinculada, lo más importante para mí es cómo planea usar la estructura. Usaré el término vector ya que ese es el término para una matriz redimensionable en C ++.

La indexación en una lista vinculada es lenta porque tiene que recorrer la lista para llegar al índice dado, mientras que un vector es contiguo en la memoria y puede llegar allí usando las matemáticas de puntero.

Agregar al final o al principio de una lista vinculada es fácil, ya que solo tiene que actualizar un enlace, donde en un vector puede tener que cambiar el tamaño y copiar el contenido.

Eliminar un elemento de una lista es fácil, ya que solo tiene que romper un par de enlaces y luego volverlos a unir. Eliminar un elemento de un vector puede ser más rápido o más lento, dependiendo de si le importa el orden. Cambiar el último elemento por encima del elemento que desea eliminar es más rápido, mientras que cambiar todo después es más lento pero conserva el orden.

Bradtgmurray
fuente
Como le dije a alguien más arriba, solo estaba tratando de relacionar la pregunta de la forma en que me la plantearon. De todos modos, nunca usaría una matriz (o una lista vinculada de roll-my-own) en C ++; usaría las versiones STL de ambos.
Onorio Catenacci
10

Eric Lippert recientemente tuvo una publicación sobre una de las razones por las cuales las matrices deben usarse de manera conservadora.

Rik
fuente
2
Es cierto que es una buena publicación, pero no es relevante en una lista vinculada versus la discusión de la matriz.
Robert Paulson
2
Sugeriría que gran parte del artículo de Eric es relevante, ya que discute las desventajas de los arreglos y las ventajas de las listas, independientemente de la implementación de la lista.
Bevan
8

La inserción y eliminación rápidas son los mejores argumentos para las listas vinculadas. Si su estructura crece dinámicamente y no se requiere acceso de tiempo constante a cualquier elemento (como las pilas dinámicas y las colas), las listas vinculadas son una buena opción.

Firas Assaad
fuente
7

Aquí hay uno rápido: la eliminación de elementos es más rápida.

itsmatt
fuente
7

Las listas enlazadas son especialmente útiles cuando la colección crece y se reduce constantemente. Por ejemplo, es difícil imaginar tratar de implementar una Cola (agregar al final, eliminar desde el frente) usando una matriz: pasarías todo tu tiempo desplazando las cosas hacia abajo. Por otro lado, es trivial con una lista vinculada.

James Curran
fuente
44
Podría tener una cola basada en matrices sin demasiado trabajo que aún fuera rápida / eficiente. Simplemente tendría que hacer un seguimiento de qué índice era la "cabeza" y cuál era la "cola". Esto funciona bastante bien si necesita una cola de tamaño fijo (por ejemplo, el búfer de teclado en un núcleo).
Herms
3
Y se llama un "búfer circular", si desea buscarlo en su referencia de algoritmo favorito.
Steve Jessop
7

Además de agregar y eliminar del medio de la lista, me gustan más las listas vinculadas porque pueden crecer y reducirse dinámicamente.

Vasil
fuente
66
Los vectores (= básicamente matrices) también pueden hacer eso y el costo amortizado para ellos suele ser menor que el de las listas debido a problemas de localidad de referencia.
Konrad Rudolph el
7

Ya nadie codifica su propia lista vinculada. Eso sería una tontería. La premisa de que usar una lista vinculada requiere más código es simplemente errónea.

En estos días, crear una lista vinculada es solo un ejercicio para que los estudiantes puedan entender el concepto. En cambio, todos usan una lista preconstruida. En C ++, basado en la descripción de nuestra pregunta, eso probablemente significaría un vector stl ( #include <vector>).

Por lo tanto, elegir una lista vinculada frente a una matriz consiste en sopesar las diferentes características de cada estructura en relación con las necesidades de su aplicación. Superar la carga adicional de programación debería tener un impacto cero en la decisión.

Joel Coehoorn
fuente
2
Er..umm .. El std :: vector es una matriz, no una lista vinculada. La lista vinculada estándar es, bueno, std :: list.
James Curran
1
Sí, pero creo que el vector está más cerca de lo que está pidiendo el operador: un reemplazo de matriz dinámica.
Joel Coehoorn
@Joel, solo estaba tratando de relacionar la pregunta tal como me la planteó este tipo que está tratando de aprender C ++. Tampoco me molestaría en codificar mi propia lista vinculada, pero así es como me lo pidió. :-)
Onorio Catenacci
En entornos con limitaciones de memoria (microcontroladores) para los que hay compiladores personalizados, no se implementa todo el lenguaje (por ejemplo, contenedores en C ++). Por lo tanto, es posible que deba codificar su propia lista vinculada. nongnu.org/avr-libc/user-manual/FAQ.html#faq_cplusplus
Minh Tran
6

Es realmente una cuestión de eficiencia, la sobrecarga para insertar, eliminar o mover (donde no se intercambia simplemente) elementos dentro de una lista vinculada es mínima, es decir, la operación en sí es O (1), versos O (n) para una matriz. Esto puede marcar una diferencia significativa si está operando fuertemente en una lista de datos. Usted elige sus tipos de datos en función de cómo los operará y elige el más eficiente para el algoritmo que está utilizando.

Steve Baker
fuente
6

Las matrices tienen sentido donde se conocerá el número exacto de elementos, y donde la búsqueda por índice tiene sentido. Por ejemplo, si quisiera almacenar el estado exacto de mi salida de video en un momento dado sin compresión, probablemente usaría una matriz de tamaño [1024] [768]. Esto me proporcionará exactamente lo que necesito, y una lista sería mucho, mucho más lenta para obtener el valor de un píxel dado. En lugares donde una matriz no tiene sentido, generalmente hay mejores tipos de datos que una lista para tratar los datos de manera efectiva.

tloach
fuente
6

Lista enlazada de matrices vs.

  1. La asignación de memoria de matriz fallará a veces debido a la memoria fragmentada.
  2. El almacenamiento en caché es mejor en matrices ya que a todos los elementos se les asigna espacio de memoria contiguo.
  3. La codificación es más compleja que las matrices.
  4. Sin restricción de tamaño en la lista vinculada, a diferencia de las matrices
  5. La inserción / eliminación es más rápida en la lista vinculada y el acceso es más rápido en las matrices.
  6. Lista enlazada mejor desde el punto de vista de subprocesos múltiples.
AKS
fuente
-1: Todo esto necesita ser justificado, no solo enumerado.
John Saunders
Cada punto ya se ha explicado en las respuestas anteriores. Al llegar tarde no tenía otra opción que enumerar. Por cierto, ¿cuál te gustaría que te explicaran?
AKS
Si ya se han explicado, ¿por qué estás respondiendo?
John Saunders
2
Para que le dé una visión resumida de la discusión. Y me gustan este tipo de respuestas para no tener que leer la misma explicación una y otra vez. Y lo hice para aquellas personas que tienen el mismo estilo de pensamiento que el mío. Diferentes personas tienen diferentes estilos. Nada nuevo.
AKS
3

Como las matrices son de naturaleza estática, por lo tanto, todas las operaciones, como la asignación de memoria, ocurren solo en el momento de la compilación. Por lo tanto, el procesador tiene que poner menos esfuerzo en su tiempo de ejecución.

debayan
fuente
3

Supongamos que tiene un conjunto ordenado, que también desea modificar agregando y eliminando elementos. Además, necesita la capacidad de retener una referencia a un elemento de tal manera que luego pueda obtener un elemento anterior o siguiente. Por ejemplo, una lista de tareas o un conjunto de párrafos en un libro.

Primero, debemos tener en cuenta que si desea retener referencias a objetos fuera del conjunto, es probable que termine almacenando punteros en la matriz, en lugar de almacenar objetos en sí mismos. De lo contrario, no podrá insertar en la matriz: si los objetos están incrustados en la matriz, se moverán durante las inserciones y cualquier puntero a ellos será inválido. Lo mismo es cierto para los índices de matriz.

Su primer problema, como ha señalado usted mismo, es la inserción: la lista vinculada permite insertar en O (1), pero una matriz generalmente requeriría O (n). Este problema se puede superar parcialmente: es posible crear una estructura de datos que proporcione una interfaz de acceso ordinal en forma de matriz donde la lectura y la escritura son, en el peor de los casos, logarítmicas.

Su segundo y más grave problema es que, dado que un elemento encuentra el siguiente elemento, es O (n). Si el conjunto no se modificó, podría retener el índice del elemento como referencia en lugar del puntero, lo que hace que find-next sea una operación O (1), pero como todo lo que tiene es un puntero al objeto en sí mismo y de ninguna manera para determinar su índice actual en la matriz que no sea escaneando toda la "matriz". Este es un problema insuperable para las matrices: incluso si puede optimizar las inserciones, no hay nada que pueda hacer para optimizar la operación de encontrar el siguiente tipo.

DenNukem
fuente
¿Podría por favor elaborar esto: "es posible crear una estructura de datos que proporcione una interfaz de acceso ordinal en forma de matriz donde la lectura y la escritura son, en el peor de los casos, logarítmicas".
Hengameh
1
Hay algunas cosas en Wikipedia en la sección Dynamic Array / Vriants. Sin embargo, no es exactamente lo que tenía en mente ... Imagine una estructura similar a un árbol b + con páginas pero sin teclas, en cambio, cada página intermedia recuerda cuántos elementos hay en cada una de las subpáginas, mientras que las páginas de la hoja simplemente sostienen el elementos en una pequeña matriz. Al insertar un elemento en una página de hoja, debe mover ~ la mitad de la página para hacer espacio, luego subir y actualizar el recuento de elementos en todas las páginas ancestrales. Cuando busque un elemento #N, simplemente sume el recuento de elementos de la página subordinada hasta que cruce N, y luego descienda a ese subárbol
DenNukem
3

En una matriz, tiene el privilegio de acceder a cualquier elemento en O (1) tiempo. Por lo tanto, es adecuado para operaciones como Binary search Quick sort, etc. La lista vinculada, por otro lado, es adecuada para la eliminación de inserción ya que está en el tiempo O (1). Ambos tienen ventajas y desventajas, y preferir uno sobre el otro se reduce a lo que desea implementar.

- La pregunta más importante es si podemos tener un híbrido de ambos. Algo así como lo que Python y Perl implementan como listas.

pranjal
fuente
3

Lista enlazada

¡Es más preferible cuando se trata de inserción! Básicamente lo que hace es que trata con el puntero

1 -> 3 -> 4

Insertar (2)

1 ........ 3 ...... 4
..... 2

Finalmente

1 -> 2 -> 3 -> 4

Una flecha de los 2 puntos en 3 y la flecha de 1 puntos en 2

¡Sencillo!

Pero de la matriz

El | 1 | 3 | 4 |

Insertar (2) | 1 | 3 | El | 4 | El | 1 | El | 3 | 4 | El | 1 | 2 | 3 | 4 |

Bueno, cualquiera puede visualizar la diferencia! Solo para 4 índices estamos realizando 3 pasos

¿Qué pasa si la longitud de la matriz es un millón entonces? ¿Es eficiente la matriz? ¡La respuesta es no! :)

¡Lo mismo ocurre con la eliminación! ¡En Linked List podemos simplemente usar el puntero y anular el elemento y el siguiente en la clase de objeto! Pero para la matriz, necesitamos realizar shiftLeft ()

¡Espero que ayude! :)

Farah Nazifa
fuente
3

La lista vinculada es más una sobrecarga para mantener que una matriz, también requiere almacenamiento de memoria adicional, todos estos puntos están de acuerdo. Pero hay algunas cosas que array no puede hacer. En muchos casos, suponga que desea una matriz de 10 ^ 9 de longitud que no puede obtener porque obtener una ubicación de memoria continua debe estar allí. La lista vinculada podría ser un salvador aquí.

Supongamos que desea almacenar varias cosas con datos, entonces se pueden extender fácilmente en la lista vinculada.

Los contenedores STL generalmente tienen una implementación de lista vinculada detrás de escena.

iec2011007
fuente
3

1- lista vinculada es una estructura de datos dinámica para que pueda crecer y reducirse en tiempo de ejecución asignando y desasignando memoria. Por lo tanto, no es necesario dar un tamaño inicial de la lista vinculada. La inserción y eliminación de nodos son realmente más fáciles.

2- el tamaño de la lista vinculada puede aumentar o disminuir en el tiempo de ejecución, por lo que no hay desperdicio de memoria. En el caso de la matriz, hay un gran desperdicio de memoria, como si declaramos una matriz de tamaño 10 y almacenamos solo 6 elementos, entonces se desperdicia espacio de 4 elementos. No existe tal problema en la lista vinculada ya que la memoria se asigna solo cuando es necesario.

3- Las estructuras de datos como la pila y las colas se pueden implementar fácilmente mediante una lista vinculada.

Ayman Amjad
fuente
2

La única razón para usar la lista vinculada es que insertar el elemento es fácil (eliminar también).

La desventaja podría ser que los punteros ocupan mucho espacio.

Y sobre eso, la codificación es más difícil: por lo general, no necesita una lista enlazada de código (o solo una vez), se incluyen en STL y no es tan complicado si aún tiene que hacerlo.

usuario15453
fuente
2
Los punteros toman mucho espacio? Realmente no. Si está almacenando una lista vinculada de booleanos, entonces, en términos de porcentaje, los punteros ocupan mucho espacio. Pero si está almacenando objetos complejos (que generalmente es el caso), entonces los punteros probablemente serían insignificantes.
Herms
olvidé la sonrisa :) Pero dije 'no' podría 'es'.
user15453
1

También creo que esa lista de enlaces es mejor que las matrices. porque hacemos un recorrido en la lista de enlaces pero no en matrices

iram Arshad
fuente
1

Dependiendo de su idioma, se podrían considerar algunas de estas desventajas y ventajas:

Lenguaje de programación C : cuando se usa una lista vinculada (a través de punteros de estructura normalmente), se debe tener especial consideración para asegurarse de que no se pierda memoria. Como se mencionó anteriormente, las listas vinculadas son fáciles de barajar, porque todo lo que hacíamos era cambiar los punteros, pero ¿vamos a recordar liberar todo?

Java : Java tiene una recolección de basura automática, por lo que la pérdida de memoria no será un problema, pero los detalles de implementación de lo que es una lista vinculada ocultan al programador de alto nivel. Métodos como eliminar un nodo del medio de la lista es un procedimiento más complicado de lo que algunos usuarios del lenguaje esperarían que fuera.

SetSlapShot
fuente
1

¿Por qué una lista vinculada sobre una matriz? Bueno, como algunos ya han dicho, mayor velocidad de inserciones y eliminaciones.

Pero tal vez no tengamos que vivir con los límites de ninguno de los dos, y obtener lo mejor de ambos, al mismo tiempo ... ¿eh?

Para las eliminaciones de matrices, puede usar un byte 'Eliminado', para representar el hecho de que se ha eliminado una fila, por lo que ya no es necesario reorganizar la matriz. Para aliviar la carga de las inserciones, o el cambio rápido de datos, use una lista vinculada para eso. Luego, cuando se refiera a ellos, haga que su lógica primero busque uno, luego el otro. Por lo tanto, usarlos en combinación le brinda lo mejor de ambos.

Si tiene una matriz realmente grande, puede combinarla con otra matriz mucho más pequeña o una lista vinculada donde la más pequeña contenga los 20, 50, 100 elementos utilizados más recientemente. Si el que necesita no está en la lista o matriz vinculada más corta, vaya a la matriz grande. Si se encuentra allí, puede agregarlo a la lista / matriz vinculada más pequeña bajo la presunción de que 'las cosas utilizadas más recientemente son las más adecuadas para ser reutilizadas' (y sí, posiblemente eliminando el elemento utilizado menos recientemente de la lista). Lo cual es cierto en muchos casos y resolvió un problema que tuve que abordar en un módulo de verificación de permisos de seguridad .ASP, con facilidad, elegancia y velocidad impresionante.

Juan Carlos
fuente
1

Si bien muchos de ustedes se han referido a los principales adv./dis de la lista vinculada frente a la matriz, la mayoría de las comparaciones son cómo uno es mejor / peor que el otro. puede hacer acceso aleatorio en la matriz, pero no es posible en la lista vinculada y otros. Sin embargo, esto supone que las listas de enlaces y la matriz se aplicarán en una aplicación similar. Sin embargo, una respuesta correcta debería ser cómo se preferiría la lista de enlaces sobre la matriz y viceversa en una implementación de aplicación particular. Supongamos que desea implementar una aplicación de diccionario, ¿qué usaría? Matriz: mmm permitiría una recuperación fácil a través de la búsqueda binaria y otros métodos de búsqueda ... pero pensemos cómo la lista de enlaces puede ser mejor ... Di que quieres buscar "Blob" en el diccionario. ¿Tendría sentido tener una lista de enlaces de A-> B-> C-> D ---->

A -> B -> C -> ...Z
|    |    |
|    |    [Cat, Cave]
|    [Banana, Blob]
[Adam, Apple]

¿Ahora es mejor el enfoque anterior o un conjunto plano de [Adam, Apple, Banana, Blob, Cat, Cave]? ¿Sería posible con una matriz? Por lo tanto, una gran ventaja de la lista de enlaces es que puede tener un elemento no solo apuntando al siguiente elemento sino también a otra lista de enlaces / matriz / montón / o cualquier otra ubicación de memoria. La matriz es una memoria unica plana dividida en bloques del tamaño del elemento que va a almacenar. La lista de enlaces, por otro lado, es un trozo de unidades de memoria que no son tuyas (puede ser de cualquier tamaño y puede almacenar cualquier cosa) y apunta a cada otro de la manera que quieras. Del mismo modo, digamos que está haciendo una unidad USB. ¿Ahora le gustaría guardar los archivos como una matriz o como una lista de enlaces? Creo que te haces una idea de lo que estoy señalando :)

Vikalp Veer
fuente