简体   繁体   English

递归反向链接列表

[英]Reverse Linked List Recursively

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. 我已经实现了迭代方法。

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. BTW:这个函数是尾递归的。 So a state-of-the-art compiler should be able to turn this recursive solution into a more efficient iterative solution. 因此,最先进的编译器应该能够将这种递归解决方案转变为更有效的迭代解决方案。

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;
}

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. 要将第一个节点放在最后,我们需要递归调用来返回指向最后一个节点的指针,以便我们可以访问它的next成员。 We stop recursing when the sub-list is null, and just return the current node. 当子列表为null时,我们停止递归,只返回当前节点。 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. 我们需要将其修复为null,因为它现在是列表的末尾。

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? 还有一个问题,我会让你思考:我们如何获得指向列表头的指针? :) :)

For each recursion, keep track of the current node and the front of the rest node. 对于每次递归,请跟踪当前节点和其余节点的前端。 Return when the rest is NULL. 当其余为NULL时返回。 After recursion returns, reverse the next field of "rest" to point to current. 递归返回后,将“rest”的下一个字段反转为指向当前。 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. 我的原始实现使用了一个sentinel节点,所以我没有在这里测试代码。 Sorry! 抱歉! Just read it as pseudocode. 只需将其读作伪代码即可。

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
}

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;
}

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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM