2009-04-27 19 views
8

Soy estudiante de informática en Alemania. Mi profesor usó la siguiente pregunta para pensar:Algoritmo para eliminar un elemento en una sola lista vinculada con O (1) complejidad

'Dada una referencia a un nodo en una sola lista vinculada (que no es el último nodo). Proporcione un algoritmo para eliminar este elemento de la lista que tiene una complejidad O (1) mientras mantiene la integridad '.

Pensé en esto, pero estoy bastante seguro de que no existe tal algoritmo. dado que es una lista vinculada única, debe pasar por todos los nodos de la lista hasta que llegue al nodo que debe eliminarse, porque debe modificar el puntero siguiente en el nodo anterior al borrado. Lo que llevaría a O (n) complejidad.

¿E-mail perdiendo cualquier cosa?

Respuesta

24

Depende de si los nodos son mutables (en valor) o no.

Hay es una manera de hacerlo, si se puede hacer lo que quiera con los nodos:

toDelete.value = toDelete.next.value 
toDelete.next = toDelete.next.next 

Toda la información de toDelete ahora se ha sobrescrito, por la información en el antiguo toDelete.next. (Dependiendo de la plataforma, puede que necesite liberar el antiguo toDelete.next, lo que significa que debe tener una referencia temporal. No es bueno si alguien más todavía tiene una referencia, por supuesto. En Java/C# simplemente lo ignoraría. .)

traté de encontrar una forma de insinuar que sin dar a la basura, pero es un poco difícil ...

no confían en que esto no es el último nodo en la lista de embargo.

+0

Ah, lo tengo. Gracias :) –

+0

tenga cuidado, como Jon explicó, que para que esto funcione, la estructura del nodo debe ser privada. Ninguno debería contener una referencia a los nodos, solo a los datos. De lo contrario, a los consumidores se les dejaría una referencia inválida al objeto toDelete.next anterior (si está en C++ por ejemplo y eliminó la estructura del nodo), o en el mejor de los casos, un objeto nodo no válido. –

+0

Esto no es realmente un "algoritmo" para eliminar un elemento de una lista de enlace único, ¿o sí? Este es el método estándar para eliminar un elemento de la lista. – Dinuk

8

no considerados exactamente la eliminación de un nodo, pero se puede copiar los datos del siguiente nodo de la corriente y elimine el nodo siguiente:

// pseudocode: 
this.data = next.data; 
var temp = this.next; 
this.next = next.next; 
delete temp; 
2

Sí. Mantiene como su puntero iterativo, un puntero al siguiente puntero de la lista anterior.

walk = &head; 
while (!match(*walk)) { 
    walk = &walk[0]->next; 
    if (!*walk) return ; 
} 
*walk = walk[0]->next; 
+0

Eso no es O (1) sin embargo. –

+0

La parte eliminada es. Un iterador de actualización en una lista vinculada debe * siempre * usar el puntero al puntero al siguiente nodo. – Joshua

3

Si los nodos son las estructuras básicas de la memoria, puede copiar el contenido del nodo "siguiente" en la posición de memoria del nodo eliminado, y desasignar la memoria en el nodo "siguiente" solía ser.

2

Suponiendo que tiene el puntero al nodo que desea eliminar. Replica el siguiente valor en el nodo actual. Reemplace el puntero actual por el nodo al que apunta.

Cuestiones relacionadas