Inverser une liste de liens de façon récursive en c

le code suivant fonctionne bien quand head est envoyé comme paramètre à lui. Comme je suis nouveau à C, Je ne pouvais pas comprendre comment cela fonctionne. Aidez moi s'il vous plaît.

struct node *recursiveReverseLL(struct node *list)
{
    struct node *revHead;
    if (list == NULL || list->link == NULL)
    {
        return list;
    }

    revHead = recursiveReverseLL(list->link);
    list->link->link = list;
    list->link = NULL; 

    return revHead;
}

Je ne sais pas comment les liens sont fournis en utilisant ces appels récursifs. ie) si les liens sont comme,

1 -> 2 -> 3 -> 4 

puis hw est-il changé,

4 -> 3 -> 2 -> 1
12
demandé sur codaddict 2012-12-29 14:25:34

8 réponses

Le général récursive de l'algorithme est la suivante:

  1. Divide la liste 2 pièces - première nœud et le reste de la liste.
  2. appeler L'inverse de façon récursive pour le rest de la liste liée.
  3. Lien restfirst.
  4. Fix head pointeur

Voici le code avec des commentaires en ligne:

struct node* recursiveReverseLL(struct node* first){

   if(first == NULL) return NULL; // list does not exist.

   if(first->link == NULL) return first; // list with only one node.

   struct node* rest = recursiveReverseLL(first->link); // recursive call on rest.

   first->link->link = first; // make first; link to the last node in the reversed rest.

   first->link = NULL; // since first is the new last, make its link NULL.

   return rest; // rest now points to the head of the reversed list.
}

j'espère que cette image va rendre les choses plus claires:

image http://geeksforgeeks.org/wp-content/uploads/2009/07/Linked-List-Rverse.gif.

52
répondu codaddict 2016-08-19 20:07:38

solution alternative:

struct node *head;
void reverse(struct node *prev, struct node *cur)
{
   if(cur){
      reverse(cur,cur->link);
      cur->link = prev;
    }
    else{
      head = prev;
    }
}

Dans main, appel inverse(NULL,tête);

5
répondu Aakash Arayambeth 2016-01-08 05:56:38
/* Reverses a linked list, returns head of reversed list
*/
NodePtr reverseList(NodePtr curr) {
    if (curr == NULL || curr->next == NULL) return curr; // empty or single element case

    NodePtr nextElement = curr->next;
    curr->next = NULL;
    NodePtr head = reverseList(nextElement);
    nextElement->next = curr;
    return head;
}
2
répondu n3wb 2017-08-11 18:11:28

une autre solution:

struct node *reverse_recur(struct node *temp)
{
    if(temp->link==NULL)
    {
        return temp;
    }

    struct node *temp1=temp->link;

    temp->link=NULL;

    return (reverse_recur(temp1)->link=temp);

}
1
répondu Sanjith Bravo Dastan 2017-08-19 08:34:17

que la liste des liens soit 1-> 2 -> 3 ->4

la fonction en c est--

struct linked_node * reverse_recursive(struct linked_node * head)
{
struct linked_node * first;/*stores the address of first node of the linked
list passed to function*/
struct linked_node * second;/* stores the address of second node of the
linked list passed to function*/
struct linked_node * rev_head;/*stores the address of last node of initial 
linked list. It also becomes the head of the reversed linked list.*/
//initalizing first and second
first=head;
second=head->next;
//if the linked list is empty then returns null
if(first=NULL)
   return(NULL);
/* if the linked list passed to function contains just 1 element, then pass
address of that element*/
if(second==NULL)
   return(first);
/*In the linked list passed to function, make the next of first element 
 NULL. It will eventually (after all the recursive calls ) make the
 next of first element of the initial linked list NULL.*/
first->next=NULL;
/* storing the address of the reverse head which will be passed to it by the
 condition if(second==NULL) hence it will store the address of last element
 when this statement is executed for the last time. Also here we assume that 
the reverse function will yield the reverse of the rest of the linked 
list.*/
rev_head=reverse(second);
/*making the rest of the linked list point to the first element. i.e. 
 reversing the list.*/
second->next=first;

/*returning the reverse head (address of last element of initial linked 
list) . This condition executes only if the initial list is 1- not empty 
2- contains more than one element. So it just relays the value of last 
element to higher recursive calls.  */
return(rev_head);
}

exécute maintenant la fonction pour la liste liée 1-> 2-> 3 -> 4

  • à l'intérieur marche arrière(&1) le code s'exécute jusqu'à ce que rev_head=reverse(&2); // ici &1 est l'adresse 1.

liste de fonction

1(première)->2(deuxième) -> 3 -> 4

  • à l'intérieur marche arrière(&2) le code s'exécute jusqu'à ce que rev_head=reverse(&3); liste des la fonction

    2(première)->3 (deuxième)-> 4

  • à l'intérieur marche arrière(&3) le code s'exécute jusqu'à ce que rev_head=reverse (&4); liste si la fonction

    3(première)-> 4 (seconde)

  • à l'intérieur marche arrière(&4) fin de la condition second = = nul est vrai donc le retour est exécuté et adresse de 4 est renvoyée.

liste des fonctions

4(première)-> NULL(seconde)

  • retour à l'arrière(&3) liste des la fonction est

    NULL<-3(premier) 4 (seconde)

    et la valeur de rev_head=&4, qui a été retournée

après l'exécution de seconde->suivant=premier; liste devient

NULL<- 3(premier) <-4 (seconde)

retour (rev_head ); est exécuté qui passe &4 parce que rev_head=&4

  • retour à la rev(&2)

liste en fonction est

NULL<-2(premier) 3(seconde)<-4

et rev_head est &4 qui a été retourné par rev (&3)

après l'exécution de seconde->suivant=tout d'abord , la liste devient

NULL<-2(premier)<-3(seconde)<-4

retour(rev_head); est exécuté, qui renvoie &4 rev(&1);

  • retour à la rev(&1)

liste en fonction est

NULL<-1(première) 2(deuxième)<-3<-4

et la valeur de rev_head est &4 qui a été adoptée par l'arrière(&3)

maintenant second- > suivant =premier est exécuté et liste devient

NULL<-1(premier) <- 2(deuxième)<-3<-4

retour(rev_head); est exécuté // rev_head=&4, qui a été retournée en arrière(&2) et la valeur de rev_head est passée à la fonction principale.

espérons que cette aide. Il m'a fallu beaucoup de temps pour comprendre cela et aussi à écrire cette réponse.

0
répondu 2017-03-21 03:14:59

c'est une belle approche que l'on peut suivre pour inverser SLL récursivement:

1.    struct node* head; // global head
2.    void rec_reverse(struct node* prev, struct node* cur)
3.    {
4.        if (cur)
5.        {
6.            rec_reverse(cur, cur->next);
7.            cur->next = prev;
8.        }
9.        else
10.            head = prev;
11.    }

Appel de la fonction de cette manière:

rec_reverse(NULL, head);

Approche:

  • appeler la fonction de façon récursive (ligne 6) Nous allons au dernier noeud de liste liée.
  • puis on met à jour head avec l'adresse du dernier noeud (ligne 10).
  • finalement, nous pointons le lien de chaque noeud à son noeud précédent (ligne 7).
0
répondu Amit Upadhyay 2017-07-31 02:47:14
    To fix head also:

void reverse_list_recursive_internal (struct list **head, struct list *node)
{
    /* last node, fix the head */
    if (node->next == NULL) {
        *head = node;
        return; 
    }
    reverse_list_recursive_internal(head, node->next);
    node->next->next = node;
    node->next = NULL;
}

void reverse_list_recursive (struct list **head)
{
    if (*head == NULL) {
        return;
    }
    reverse_list_recursive_internal(head, *head);
}
0
répondu Krishna Durgam 2017-10-22 06:17:42

Il me semble que personne n'a proposé un algorithme qui est queue-récursive. En principe, un algorithme récursif peut être compilé sans pile (à condition que le compilateur soit suffisamment intelligent), produisant ainsi du code qui consomme moins de mémoire.

supposons TList est un type de données personnalisé pour une liste mono-liée, c'est un pointeur vers une structure qui comme un link champ pour accéder à l'élément suivant dans la liste.

l'algorithme est La suivantes:

``

TList reverse_aux(TList l, TList solution) {
    if (l == NULL) {
        return solution;
    } else {
        TList tmp = l->link;
        l->link = solution;
        return reverse_aux(tmp, l);
    }
}

TList reverse(TList l) {
    return reverse_aux(l, NULL);
}

``

0
répondu FSp 2018-05-23 14:03:32