使用递归反转链表

Posted

技术标签:

【中文标题】使用递归反转链表【英文标题】:Reversing Linked List using Recursion 【发布时间】:2018-11-12 08:13:10 【问题描述】:

我希望能够编写一个递归函数来反转一个链表。假设所有元素都已附加到列表中。

我想给head赋值head->next->next,所以node->next的下一个节点就是节点本身。然后,当递归完成时,将链表的头(this->head)分配给最终节点(即头)。

还缺少将最终节点的 next 分配为 NULL。

在任何世界上都会有这样的工作吗?它给出了运行时/分段错误。

struct node 
    int data;
    node *next;
;

class LinkedList
    node *head = nullptr;
public:
    node *reverse(node *head)
        if(head->next != nullptr)
            reverse(head->next)->next = head;
        
        else
            this->head = head;
        
        return head;
    
;

【问题讨论】:

所以你的链表中的每个节点除了指向下一个节点的指针之外,还有一个指向链表头的指针(this->head)?这似乎是不标准的(我希望每个节点只包含数据和指向下一个节点的指针)。您可能希望在问题中包含节点的结构。 【参考方案1】:

请注意,您忽略了 head 本身是 nullptr 的情况。另外,你不能只返回head...你需要返回reversed列表的头部。

试试这个:

node* reverse_list(node* head) 
    if (head == nullptr or head->next == nullptr)  return head; 
    auto tail = head->next;
    auto reversed_tail = reverse_list(tail);
    // tail now points to the _last_ node in reversed_tail,
    // so tail->next must be null; tail can't be null itself        
    tail->next = head; 
    head->next = nullptr;
    return reversed_tail;

(未测试...)

【讨论】:

【参考方案2】:

列表反转函数必须是尾递归的,否则在递归长列表时会溢出堆栈。例如:

node* reverse(node* n, node* prev = nullptr) 
    if(!n)
        return prev;
    node* next = n->next;
    n->next = prev;
    return reverse(next, n);

可以更轻松地内联迭代列表还原:

inline node* reverse(node* n) 
    node* prev = nullptr;
    while(n) 
        node* next = n->next;
        n->next = prev;
        prev = n;
        n = next;
    
    return prev;

【讨论】:

以上是关于使用递归反转链表的主要内容,如果未能解决你的问题,请参考以下文章

剑指Offer-反转链表

单向链表反转,就地逆置与递归反转(无表头结点)

递归地反转Java中的链表

递归:反转链表

递归:反转链表

Leetcode练习(Python):链表类:第206题:反转链表:反转一个单链表。