¿Cómo funciona el proceso de eliminación en una lista vinculada? ¿Es solo eliminando la referencia del nodo? ¿Qué mecanismo se utiliza para disponer un nodo?

Depende de cómo el entorno de tiempo de ejecución que esté utilizando gestione la memoria.

Por ejemplo, en C, debe asignar explícitamente memoria para un nodo llamando a malloc() , y luego elimina el nodo, debe devolver su memoria a la lista de espacios free() llamando a free() . Los datos en el nodo se encuentran donde sea que estén en la memoria hasta que malloc() reutilice, por lo que puede obtener errores horribles en C al retener un puntero a un nodo después de que lo haya liberado, ya que los datos siguen ahí hasta que de repente no lo es

En los idiomas recolectados de basura, eliminar todas las referencias a un nodo libera automáticamente la memoria cuando se ejecuta el recolector de basura.

Existen diferentes enfoques para este problema. C # realiza un seguimiento de cuántas referencias existen a un objeto y el GC lo recopila cuando el número es cero. Go utiliza un algoritmo de marca / barrido, donde establece un bit en cada objeto en el montón al que puede navegar desde la raíz, y luego recoge cada objeto en el montón cuyo bit no se configuró. (En ambos casos, nada puede asignar nueva memoria mientras se ejecuta el GC, y el tiempo de ejecución esencialmente detiene el programa mientras está limpiando la casa. La recolección de basura de todo el mundo es la razón por la cual los sistemas en tiempo real generalmente todavía se escriben en C.)

En cualquier caso, el GC pasa por el montón y devuelve todo lo que se recopila a la lista de espacio libre. Tal vez incluso compacta el montón, moviendo bloques de memoria usada alrededor para que más espacio libre sea contiguo.

Entonces, en un lenguaje GC, eliminas un nodo de la lista haciendo que nada lo señale más. Por lo general, esto se parece a n.prev.next = n.next . Antes de esta operación, lo único que apuntaba a n era n.prev.next ; Después de esta operación, nada lo hace. (De acuerdo, eso no es cierto. n todavía apunta a la memoria. Pero cuando n sale del alcance al final del método, entonces nada lo señalará). La próxima vez que se ejecute el GC, encontrará que nada apunta al memoria a la que n solía señalar (ya sea porque la fase de marcado no lo marcó o porque su recuento de referencia fue a 0), y coloca el bloque de memoria que solía contener n en la lista de espacio libre.

En C, después de hacer n.prev.next = n.next , debe llamar free(n) o tendrá lo que se conoce como pérdida de memoria. Su programa agregará nodos a la lista y los eliminará, pero al eliminarlos no se agregarán nodos eliminados a la lista de espacios libres y, finalmente, el programa se quedará sin memoria libre.

Pseudocódigo (C / ++ / # – like):

(objeto) * this = currentNode;
this-> next-> prev = this-> prev;
this-> prev-> next = this-> next;
this.dispose ();

dispose () se puede implementar de muchas maneras según el idioma y el entorno. En realidad, podría marcar la memoria como no utilizada, liberar el bloque de memoria para la recolección de basura, marcarlo como disponible, etc.

Necesita separar dos mecanismos.

Uno es la estructura de la lista.

El otro es el sistema de asignación de memoria, que forma parte del sistema operativo. Funciona como un recuadro negro: pides un trozo de memoria y, cuando termines, lo vuelves a abandonar.

Internamente, el sistema de asignación de memoria mantiene todo tipo de información de mantenimiento utilizando estructuras de datos propias (posiblemente incluyendo más listas vinculadas). Pero generalmente no te enfrentas a eso mientras escribes tu programa.

Entonces, cuando elimina un nodo en una lista vinculada, eso implica estos pasos:

  • Redireccionar el enlace o enlaces que apuntan a ese nodo
  • Dígale al subsistema de memoria que ya no necesita la memoria asociada con ese nodo.

More Interesting

¿Qué cosas teóricas debo aprender sobre informática?

¿Cuánto conocimiento matemático profundo deberías tener como diseñador de juegos?

¿Puedo obtener el código fuente para la exponenciación de bases fraccionarias con exponentes fraccionales en Java al igual que la función Math.pow pero sin usar la función?

¿Quién decidió que, en una lista de principios científicos, la numeración comienza con cero en lugar de uno?

¿Cómo los operadores matemáticos mapean objetos de un punto a otro en el espacio?

¿Cuál es el grado de una ecuación polinómica que tendría una raíz constructiva real positiva de esta forma, [math] \ sqrt {2} + \ sqrt [4] {3} [/ math]?

¿Por qué el lenguaje de las palabras a * b * es decidible?

Cómo encontrar un algoritmo para encontrar tanto el mínimo como el máximo de n números usando menos de 3n / 2 comparaciones

¿Hay una manera eficiente de comparar la similitud de una cadena con cada permutación de otra cadena (es decir, un grupo simétrico)?

¿Existe un término en matemáticas como 'real-complete' para describir una función que mapea todos los elementos de un conjunto (número real por ejemplo) a otro conjunto, o 'posibilidad-completa' para describir un algoritmo que maneja todas las posibilidades de entrada? ?

¿A qué escuela debo asistir para un programa de posgrado de matemáticas: Stony Brook o UIUC?

¿Cuál es una buena manera de aprender y comprender la escritura dependiente en un idioma como Idris / Coq / Agda?

¿Cómo se mejora su escritura técnica / científica?

Dada una instancia tautológica de DNF-SAT, ¿se conserva la tautología después de agregar un nuevo literal [math] v [/ math] o [math] \ bar {v} [/ math] a una cláusula que se sabe que está en PTIME?

¿Será difícil ingresar a una escuela de posgrado en astronomía de un entorno no tradicional (especializaciones diferentes a astronomía, física, matemáticas, CS, etc.)?