La recursión es solo llamar a una función varias veces.
La clave para entender es que cuando se vuelve a llamar a la función, el estado anterior se almacena por separado en la pila de memoria. Llame a esto un estado de función si puede. Cada uno de estos estados de función que se almacenan en la pila de memoria tienen valores de variables iguales a los valores durante su ejecución.
Tomando un ejemplo.
Tome esta implementación geeksforgeeks de reversión de una lista vinculada.
- Soy un ciudadano estadounidense que se mudó a los EE. UU. Después de vivir en el extranjero toda mi vida. Además de la identificación / licencia y la seguridad social, ¿de qué otra cosa se debe ocupar?
- Tengo 34 años y tengo ansiedad por trastornos alimentarios y estoy tomando medicamentos contra la depresión. Me han tratado en NIMHANS Bangalore durante los últimos 3 años, pero ahora estoy en Gurgaon. ¿Dónde debo ir a buscar y encontrar un buen psiquiatra en Gurgaon o Delhi, donde las tarifas no son demasiado altas?
- ¿Por qué no soy consistente en el billar?
- Soy nuevo en TopCoder. ¿Qué es Div1 y Div2 en TopCoder?
- ¿Por qué mis dos conejillos de indias disfrutan abrazarse, lamerse o abrazarse cuando ambos son jabalíes?
void recursiveReverse(struct node** head_ref)
{
struct node* first;
struct node* rest; /* empty list */
if (*head_ref == NULL)
return; /* suppose first = {1, 2, 3}, rest = {2, 3} */
first = *head_ref;
rest = first->next; /* List has only one node */
if (rest == NULL)
return; /* reverse the rest list and put the first element at the end */
recursiveReverse(&rest);
first->next->next = first; /* tricky step -- see the diagram */
first->next = NULL; /* fix the head pointer */
*head_ref = rest;
} int main()
{ node *head = newNode(1);
head->next = newNode(2);
head->next->next = newNode(3); recursiveReverse(&head);
return 0;
}
void recursiveReverse(struct node** head_ref)
{
struct node* first;
struct node* rest; /* empty list */
if (*head_ref == NULL)
return; /* suppose first = {1, 2, 3}, rest = {2, 3} */
first = *head_ref;
rest = first->next; /* List has only one node */
if (rest == NULL)
return; /* reverse the rest list and put the first element at the end */
recursiveReverse(&rest);
first->next->next = first; /* tricky step -- see the diagram */
first->next = NULL; /* fix the head pointer */
*head_ref = rest;
} int main()
{ node *head = newNode(1);
head->next = newNode(2);
head->next->next = newNode(3); recursiveReverse(&head);
return 0;
}
void recursiveReverse(struct node** head_ref)
{
struct node* first;
struct node* rest; /* empty list */
if (*head_ref == NULL)
return; /* suppose first = {1, 2, 3}, rest = {2, 3} */
first = *head_ref;
rest = first->next; /* List has only one node */
if (rest == NULL)
return; /* reverse the rest list and put the first element at the end */
recursiveReverse(&rest);
first->next->next = first; /* tricky step -- see the diagram */
first->next = NULL; /* fix the head pointer */
*head_ref = rest;
} int main()
{ node *head = newNode(1);
head->next = newNode(2);
head->next->next = newNode(3); recursiveReverse(&head);
return 0;
}
void recursiveReverse(struct node** head_ref)
{
struct node* first;
struct node* rest; /* empty list */
if (*head_ref == NULL)
return; /* suppose first = {1, 2, 3}, rest = {2, 3} */
first = *head_ref;
rest = first->next; /* List has only one node */
if (rest == NULL)
return; /* reverse the rest list and put the first element at the end */
recursiveReverse(&rest);
first->next->next = first; /* tricky step -- see the diagram */
first->next = NULL; /* fix the head pointer */
*head_ref = rest;
} int main()
{ node *head = newNode(1);
head->next = newNode(2);
head->next->next = newNode(3); recursiveReverse(&head);
return 0;
}
void recursiveReverse(struct node** head_ref)
{
struct node* first;
struct node* rest; /* empty list */
if (*head_ref == NULL)
return; /* suppose first = {1, 2, 3}, rest = {2, 3} */
first = *head_ref;
rest = first->next; /* List has only one node */
if (rest == NULL)
return; /* reverse the rest list and put the first element at the end */
recursiveReverse(&rest);
first->next->next = first; /* tricky step -- see the diagram */
first->next = NULL; /* fix the head pointer */
*head_ref = rest;
} int main()
{ node *head = newNode(1);
head->next = newNode(2);
head->next->next = newNode(3); recursiveReverse(&head);
return 0;
}
void recursiveReverse(struct node** head_ref)
{
struct node* first;
struct node* rest; /* empty list */
if (*head_ref == NULL)
return; /* suppose first = {1, 2, 3}, rest = {2, 3} */
first = *head_ref;
rest = first->next; /* List has only one node */
if (rest == NULL)
return; /* reverse the rest list and put the first element at the end */
recursiveReverse(&rest);
first->next->next = first; /* tricky step -- see the diagram */
first->next = NULL; /* fix the head pointer */
*head_ref = rest;
} int main()
{ node *head = newNode(1);
head->next = newNode(2);
head->next->next = newNode(3); recursiveReverse(&head);
return 0;
}
void recursiveReverse(struct node** head_ref)
{
struct node* first;
struct node* rest; /* empty list */
if (*head_ref == NULL)
return; /* suppose first = {1, 2, 3}, rest = {2, 3} */
first = *head_ref;
rest = first->next; /* List has only one node */
if (rest == NULL)
return; /* reverse the rest list and put the first element at the end */
recursiveReverse(&rest);
first->next->next = first; /* tricky step -- see the diagram */
first->next = NULL; /* fix the head pointer */
*head_ref = rest;
} int main()
{ node *head = newNode(1);
head->next = newNode(2);
head->next->next = newNode(3); recursiveReverse(&head);
return 0;
}
void recursiveReverse(struct node** head_ref)
{
struct node* first;
struct node* rest; /* empty list */
if (*head_ref == NULL)
return; /* suppose first = {1, 2, 3}, rest = {2, 3} */
first = *head_ref;
rest = first->next; /* List has only one node */
if (rest == NULL)
return; /* reverse the rest list and put the first element at the end */
recursiveReverse(&rest);
first->next->next = first; /* tricky step -- see the diagram */
first->next = NULL; /* fix the head pointer */
*head_ref = rest;
} int main()
{ node *head = newNode(1);
head->next = newNode(2);
head->next->next = newNode(3); recursiveReverse(&head);
return 0;
}
void recursiveReverse(struct node** head_ref)
{
struct node* first;
struct node* rest; /* empty list */
if (*head_ref == NULL)
return; /* suppose first = {1, 2, 3}, rest = {2, 3} */
first = *head_ref;
rest = first->next; /* List has only one node */
if (rest == NULL)
return; /* reverse the rest list and put the first element at the end */
recursiveReverse(&rest);
first->next->next = first; /* tricky step -- see the diagram */
first->next = NULL; /* fix the head pointer */
*head_ref = rest;
} int main()
{ node *head = newNode(1);
head->next = newNode(2);
head->next->next = newNode(3); recursiveReverse(&head);
return 0;
}
void recursiveReverse(struct node** head_ref)
{
struct node* first;
struct node* rest; /* empty list */
if (*head_ref == NULL)
return; /* suppose first = {1, 2, 3}, rest = {2, 3} */
first = *head_ref;
rest = first->next; /* List has only one node */
if (rest == NULL)
return; /* reverse the rest list and put the first element at the end */
recursiveReverse(&rest);
first->next->next = first; /* tricky step -- see the diagram */
first->next = NULL; /* fix the head pointer */
*head_ref = rest;
} int main()
{ node *head = newNode(1);
head->next = newNode(2);
head->next->next = newNode(3); recursiveReverse(&head);
return 0;
}
Deje que el enlace que estamos invirtiendo sea 1-> 2-> 3
ahora en la primera llamada de función
head_ref tiene la dirección del nodo (1)
primeros puntos a 1
el resto apunta al primero-> siguiente, que es el nodo (2)
ahora repetimos. Ahora los valores anteriores se guardan en un estado separado y se almacenan en la pila.
ahora se creará un estado completamente nuevo para esta función llamada donde
head_ref tiene la dirección del nodo (2)
primeros puntos a 2
el resto apunta al primero-> siguiente, que es el nodo (3)
volvemos a repetir y los valores anteriores se almacenan en otro estado en la pila.
ahora nuevamente se creará un estado completamente nuevo para esta llamada de función donde
head_ref tiene la dirección del nodo (3)
primeros puntos a 3
puntos de descanso a NULL
ahora que rest == NULL volvemos a nuestro estado anterior.
en este estado los valores son:
primeros puntos a 2
el resto apunta al primero-> siguiente, que es el nodo (3)
así que después de las manipulaciones del puntero, la lista vinculada se volvería así
1-> 2 <-3
head_ref ahora almacena la dirección del nodo (3)
y volvemos a nuestro primer estado donde
primeros puntos a 1
el resto apunta al primero-> siguiente, que es el nodo (2)
pero dado que la dirección de descanso se pasó durante la llamada recursiva. cambiamos el valor de rest cuando realizamos * head_ref = rest antes de regresar.
después de la manipulación, la lista ahora se convierte
1 <-2 <-3
esta es nuestra primera llamada de función donde head_ref era el puntero real de la lista vinculada desde donde se llamó. * head_ref = rest en la llamada anterior cambia el valor del puntero rest en esta llamada de función, por lo que rest ahora apunta al nodo (3).
y realizar * head_ref = rest cambia nuestra cabeza original para que apunte al nodo (3).
invirtiendo así la lista vinculada.