递归反转链表

问题描述 投票:0回答:8

我在链表中定义了一个节点:

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

我想递归地反转链表。我将头指针传递给函数。我的函数定义如下:

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

我应该如何进行?我已经实现了迭代方法。

c linked-list
8个回答
9
投票

它应该按如下方式工作:

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

首先,开始:

reverseLinkedListRecursively(linkedList, NULL);

顺便说一句:这个函数是尾递归的。因此,最先进的编译器应该能够将这种递归解决方案转变为更高效的迭代解决方案。


6
投票
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;
}

2
投票

要递归地反转链表,我们(递归地)反转由除第一个节点之外的所有内容组成的子列表,然后将第一个节点放在末尾。要将第一个节点放在末尾,我们需要递归调用返回指向最后一个节点的指针,以便我们可以访问其

next
成员。当子列表为空时,我们停止递归,只返回当前节点。将第一个节点附加到递归调用结果的末尾后,当我们从当前递归调用返回时,第一个节点就是“最后一个节点”。还有一个最后的细节:原始的第一个节点(现在是最后一个)仍将指向原始的第二个节点(现在是倒数第二个)。我们需要将其修复为空,因为它现在是列表的末尾。

因此:

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

还有一个问题,我会让你思考一下:我们如何获得指向列表的 new 头的指针? :)


1
投票

对于每次递归,跟踪当前节点和其余节点的前面。当其余为 NULL 时返回。递归返回后,反转“rest”的下一个字段以指向当前。为了跟踪新的第一个节点,递归函数只需将旧的最后一个节点传回。

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

我原来的实现使用了哨兵节点,所以我没有在这里测试代码。对不起!只需将其作为伪代码读取即可。


1
投票
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
}

0
投票

如果要反转列表,则节点结构中必须有先前的节点指针:

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

并且你的列表必须有指向头和尾的指针:

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

0
投票

大家好,下面找到了带递归和不带递归的反转链表的程序,希望这对您有所帮助。

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

0
投票

请找到解决方案:- 最初开始于。 头=反向递归(头); //函数调用

//实际功能

struct Node * reverse_recursion(struct Node * head)

{
static struct Node *p;
if(head->link == NULL)
{
    p = head;
    return head;
}
reverse_recursion(head->link);
struct Node* prev = head->link;
prev->link = head;
head->link = NULL;
return p;
}
© www.soinside.com 2019 - 2024. All rights reserved.