Reverse Linked List Recursively

只谈情不闲聊 提交于 2019-12-03 19:38:55

问题


I have a Node defined in Linked List as:

typedef struct abc
{
    int id;
    struct abc *next;        
}node;

I want to reverse a Linked List recursively.I am passing the head pointer to the function. My function definition looks like:

node *reverseLinkedListRecursively(node *head)
{
    node *current;
    node *rest;
    if(head == NULL)
        return head;

    current=head;
    rest=head->next;

    if(rest == NULL)
    {
       return rest;
    }
    reverseLinkedListRecursively(rest);
    current->next->next=rest;
    current->next=NULL;
    return rest;
}

How should I proceed? I have implemented the iterative approach.


回答1:


It should work as follows:

node *reverseLinkedListRecursively(node *rest, node *reversed)
{
    node *current;

    if (rest == NULL)
        return reversed;

    current = rest;
    rest = rest->next;
    current->next = reversed;

    return reverseLinkedListRecursively(rest, current);
}

Initially, start it with:

reverseLinkedListRecursively(linkedList, NULL);

BTW: This function is tail-recursive. So a state-of-the-art compiler should be able to turn this recursive solution into a more efficient iterative solution.




回答2:


node *reverseLinkedListRecursively(node *head)
{
    node *current;
    node *rest;
    if(head == NULL)
        return head;


    current=head;
    rest=head->next;

    if(rest == NULL)
    {
        /* Wrong. Think about the simple case of a one-element list.
           Your code will return NULL as the reversed list. */
        //return rest;
        return current;
    }
    /* You lost the return value, which will be the beginning of the reversed 'rest'. */
    //reverseLinkedListRecursively(rest);
    rest = reverseLinkedListRecursively(rest);

    /* current->next points to the last element in the reversed 'rest'.
       What do you want that to point to? */
    //current->next->next=rest;
    current->next->next = current; // temporarily circular
    current->next=NULL;

    /* Now you can return rest, since you set it to the beginning of the reversed list. */
    return rest;
}



回答3:


To reverse a linked list recursively, we reverse (recursively) the sub-list that consists of everything except the first node, and then put the first node at the end. To put the first node at the end, we need the recursive call to return a pointer to the last node, so that we can access its next member. We stop recursing when the sub-list is null, and just return the current node. After we attach the first node to the end of the recursive-call results, that first node is the "last node" when we return from the current recursive call. There is one final detail: the original first node (now last) will still be pointing to the original second node (now second-last). We need to fix that to be null, since it's now the end of the list.

Thus:

node* reverseLinkedListHelper(node* head) {
    if (head->next == NULL) { return head; }
    node* last = reverseLinkedListRecursively(head->next);
    last->next = head;
    return head;
}

void reverseLinkedList(node* head) {
    assert (head != NULL);
    reverseLinkedListHelper(head);
    head->next = NULL;
}

There's one more problem, that I'll let you think about: how do we get a pointer to the new head of the list? :)




回答4:


For each recursion, keep track of the current node and the front of the rest node. Return when the rest is NULL. After recursion returns, reverse the next field of "rest" to point to current. To keep track of the new first node, the recursive function just pass the old last node back.

void recursive_reverse() {
    // driver for the recursive reverse function.
    // first is a data member of linked list that point to the first node of list.
    first = recursive_reverse(first, first->next);
}

Node* recursive_reverse(Node *current, Node *rest) {
    // if rest == NULL, the current must be the old last node,
    // which is also the new first node
    if (rest == NULL) return current;
    Node *new_first = recursive_reverse(current->next, rest->next);

    // rearrange pointers
    rest->next = current;
    current->next = NULL;

    // pass along the new first node
    return new_first;
}

My original implementation uses a sentinel node, so I didn't test the code here. Sorry! Just read it as pseudocode.




回答5:


void RecursiveReverse(struct node** headRef)  
{  
    struct node* first;  
    struct node* rest; 

    if (*headRef == NULL) return; // empty list base case

    first = *headRef; // suppose first = {1, 2, 3}
    rest = first->next; // rest = {2, 3}

    if (rest == NULL) return; // empty rest base case
    RecursiveReverse(&rest); // Recursively reverse the smaller {2, 3} case after: rest = {3, 2}

    first->next->next = first; // put the first elem on the end of the list
    first->next = NULL; // (tricky step -- make a drawing)

    *headRef = rest; // fix the head pointer
}



回答6:


If you want to reverse a list you must have previous node pointers in your node struct:

typedef struct abc
{
    int id;
    struct abc *next;
    struct abc *prev;        
}node;

and your list must have pointers to head and tail:

typedef struct list
{
    node * first;
    node * last;
} list;



回答7:


Hey guys find the programs for reversing linked list with and without recursion below, hope this will help u.

LINK *reverse_linked_list_recursion(LINK *head)
{
        LINK *temp;
        if (!head) {
                printf("Empty list\n");
                return head;
        }
        else if (!head->next)
                return head;
        temp = reverse_linked_list_recursion(head->next);
        head->next->next = head;
        head->next = NULL;
        return temp;
}

LINK *reverse_linked_list_without_recursion(LINK *head)
{
        LINK *new, *temp;
        if (!head) {
                printf("No element in the list\n");
                return head;
        }
        else {
                new = head;
                while (head->next) {
                        temp = head->next;
                        head->next = temp->next;
                        temp->next = new;
                        new = temp;
                }
        }
        return new;
}


来源:https://stackoverflow.com/questions/7963293/reverse-linked-list-recursively

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!