¿Qué hace exactamente node = node-> next en una lista vinculada?

En primer lugar, la estructura debería ser así (también he cambiado el nombre de las variables para una mejor comprensión)

nodo de estructura
{
datos int;
struct node * next;
};

Entonces, el nodo raíz se puede crear así

nodo rootNode;
rootNode.data = 1;
rootNode.next = NULL;

Ahora agreguemos un nodo más a la lista (que actualmente contiene solo un nodo, es decir, rootNode)

nodo newNode;
newNode.data = 2;
newNode.next = NULL;
// asigna su dirección al siguiente de rootNode
rootNode.next = & newNode;

Se puede seguir a Sane para agregar más nodos a la lista (cuyo nodo inicial es rootNode y que actualmente tiene dos nodos

La lista se puede recorrer como debajo

nodo * currentNode = & rootNode;
while (currentNode! = NULL)
{
printf (“NodeData =% d” * currentNode-> data);

// pasar al siguiente nodo (que es newNode que agregamos anteriormente)
currentNode = currentNode-> next;
}

Lo siguiente será la salida

NodeData = 1
NodeData = 2

Ahora para sus preguntas

  • ¿Qué hace nodo = nodo-> siguiente exactamente mientras recorre la lista vinculada

Respuesta : En su caso, el nodo es un puntero.
Diga un puntero una dirección de retención del nodo que se encuentra en la ubicación ‘100’
Y digamos que un nodo-> siguiente contiene una dirección de nodo que está en la ubicación ‘102’

Entonces, el nodo contiene la dirección ‘100’
Mientras el nodo-> siguiente contiene la dirección ‘102’

Entonces nodo = nodo-> siguiente hará que el nodo mantenga la dirección ‘102’

  • No es el puntero del siguiente elemento al puntero en la variable de nodo

Respuesta : Siguiente contiene un puntero a una variable Nodo. Es un puntero a una estructura de Nodo completa y no solo una variable próxima en una estructura.

La dura respuesta de Joharis ya cubre el punto crucial del concepto. Trataré de ayudarte a visualizar.

Ahora, ¿qué es un puntero? Apunta a la dirección o ubicación de una variable. Así que supongamos que la lista de estructura está en la dirección 0x100000. Luego se crea el miembro del nodo de la estructura, que es otro puntero. Supongamos que el nodo se crea en una ubicación aleatoria, 0x123456. Así que ahora cuando haces nodo-> nodo, apunta a esta nueva ubicación. Esto sigue y sigue.

cuando agrega un nuevo nodo a su lista vinculada, hace algo como esto:
(para el primer nodo) node = (struct list *) malloc (sizeof (struct list))
(para el siguiente nodo) node-> next = (struct list *) malloc (sizeof (struct list))

Entonces, en la primera instrucción, se asigna un bloque de memoria y el puntero al mismo se asigna al nodo de puntero de estructura. Posteriormente, cuando agrega otro nodo al final de la lista existente (que ahora consta de un solo nodo), hace lo mismo y asigna el puntero al siguiente puntero de nodo.

Ahora suponga que tiene una larga lista y desea agregar un nuevo nodo al final. Entonces, antes que nada tienes que encontrar el final. Por lo general, el siguiente puntero al último nodo es un puntero nulo. Ya sabes el comienzo de la lista. Por lo tanto, debe acceder al siguiente nodo hasta que encuentre que el puntero es nulo.

Pero como puedo ver en la pregunta, está reasignando el puntero de la cabeza. Existe la posibilidad de perder la referencia para siempre. Por lo tanto, es mejor hacerlo usando un puntero temporal en lugar de usar el puntero del cabezal.

Algunos “consejos” para ti, ja, ja (me refiero a consejos) …

  1. Solo como una cuestión de sintaxis C, necesita un punto y coma después de su declaración de estructura … en este caso, el punto y coma debe aparecer justo después de “* nodo” … su código de ejemplo omitió esto.
  2. Además, declarar * nodo declara un puntero a un nodo, pero aún no tiene una instancia real de esta estructura; Necesitará crear al menos una o dos instancias antes de hacer cualquier cosa.
  3. Antes de usar node = node-> next para recorrer la lista, recuerde que es muy importante inicializar junto a NULL (o nullptr en C ++ 11); Esto indica el final de la lista. Cuando agrega un nuevo nodo después del actual, luego apuntará a un valor no nulo.
  4. Además, antes de recorrer la lista, deberá realizar la prueba a continuación. Si es NULL, entonces ejecutar node = node-> next establecería el nodo en NULL y será mejor que te detengas.

Entonces, con la corrección de sintaxis en (1) anterior, la declaración adecuada sería:

lista de estructura
{
datos int;
lista de estructura * siguiente;
} * nodo; // ¡NOTA USO DE SEMICOLON!

Tenga en cuenta que con C ++, podría haber inicializado a NULL de manera predeterminada escribiendo un constructor, pero supongo que C aquí. En C, tendrá que hacer la inicialización usted mismo. También recuerde crear una instancia, o no tendrá nada con qué trabajar.

lista de estructuras a_node; // Esto crea una instancia de la estructura
nodo = * un_nodo; // Punto a esto
nodo-> siguiente = NULL; // Inicializa el miembro llamado “siguiente”

En realidad, es más común usar malloc para crear una instancia, en cuyo caso obtendrá un puntero a la instancia.

lista de estructura * nodo2;
nodo2 = (lista de estructura *) malloc (tamaño de (lista de estructura));
nodo2-> siguiente = NULL;

Por cierto, esto funciona mucho más suavemente en C ++, con la ayuda de “nuevo”.

Finalmente, podemos unir un nodo a otro …

nodo-> siguiente = nodo2; // Coloca * node2 después de * node.

Espero que esto ayude.

Independientemente de la estructura que haya establecido, significa que su nodo actual apuntará al siguiente nodo (en un lenguaje simple que cree que su nodo actual se convirtió en el siguiente nodo), eso significa que en realidad contendrá la dirección del siguiente nodo.

Cuando recorre una matriz (digamos arr), escribe ‘arr ++’ o ‘arr = arr + 1’ porque la matriz es una asignación contigua de memoria.
De la misma manera para recorrer una lista vinculada (que no es una memoria contigua) necesita ‘nodo = nodo-> siguiente’ ya que la dirección del siguiente nodo se almacena en el campo ‘siguiente’ de cada estructura.
Suponiendo que almacena correctamente la dirección del nuevo nodo mientras lo crea