20

当 head 作为参数发送给它时,以下代码可以正常工作。由于我是 C 新手,所以我无法理解它是如何工作的。请帮帮我。

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

我不知道如何使用这些递归调用提供链接。即)如果链接是,

1 -> 2 -> 3 -> 4 

那么它是如何改变的,

4 -> 3 -> 2 -> 1
4

9 回答 9

68

通用的递归算法是:

  1. Divide部分列表2- 第一个节点和列表的其余部分。
  2. 递归调用rest链表的反向。
  3. 链接restfirst
  4. 修复head指针

这是带有内联注释的代码:

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

我希望这张图片能让事情更清楚:

图片
(来源:geeksforgeeks.org

于 2012-12-29T10:35:48.160 回答
6

替代解决方案:

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

在 main 中,调用 reverse(NULL,head);

于 2016-01-08T05:56:38.093 回答
3
/* 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;
}
于 2017-08-11T18:11:28.337 回答
2

另一种解决方案:

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

}
于 2014-07-19T04:44:37.837 回答
2

让链表为 1-> 2 -> 3 ->4

c中的函数是--

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

现在运行链表 1-> 2-> 3 -> 4 的函数

  • 在 reverse(&1) 中,代码一直运行到 rev_head=reverse(&2); // 这里&1是1的地址。

函数列表是
1(first)->2(second) -> 3 -> 4

  • 内部 reverse(&2) 代码运行直到 rev_head=reverse(&3); 功能列表
    2(first)->3 (second)-> 4

  • 内部 reverse(&3) 代码运行直到 rev_head=reverse (&4); 列出函数
    3(first)-> 4(second)

  • 内部 reverse(&4) 终止条件 second==NULL 为真,因此执行 return 并返回 4 的地址。

功能列表

4(第一)-> NULL(第二)

  • 返回 reverse(&3) 函数列表为
    NULL<-3(first) 4 (second)
    并且返回的 rev_head=&4 的值

执行第二个->下一个=第一个后;列表变成

NULL<- 3(第一)<-4(第二)

返回(rev_head);执行通过 &4 因为 rev_head=&4

  • 返回 rev(&2)

函数中的列表是

NULL<-2(第一)3(第二)<-4

rev_head 是 &4 由 rev(&3) 返回

执行 second->next=first 后,列表变为

NULL<-2(第一)<-3(第二)<-4

返回(rev_head);执行返回 &4 到 rev(&1);

  • 回到 rev(&1)

函数中的列表是

NULL<-1(第一)2(第二)<-3<-4

rev_head 的值为 &4,由 reverse(&3) 传递

现在执行 second->next =first 并且列表变为

NULL<-1(第一)<- 2(第二)<-3<-4

返回(rev_head);执行 // rev_head=&4 由 reverse(&2) 返回,并将 rev_head 的值传递给主函数。

希望这可以帮助。我花了很多时间来理解这一点并写下这个答案。

于 2017-03-21T03:14:59.443 回答
0
    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);
}
于 2017-04-16T13:45:14.663 回答
0

这是一种可以递归地反转 SLL 的漂亮方法:

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

以这种方式调用函数:

rec_reverse(NULL, head);

方法:

  • 递归调用函数(第 6 行),我们转到链表的最后一个节点。
  • 然后我们用最后一个节点的地址更新 head(第 10 行)。
  • 最后,我们将每个节点的链接指向它的前一个节点(第 7 行)。
于 2017-07-30T17:47:55.520 回答
0

在我看来,没有人提出过尾递归算法。原则上,尾递归算法可以在没有堆栈的情况下编译(前提是编译器足够聪明),从而生成消耗更少内存的代码。

假设TList是单链表的自定义数据类型,它是一个指向结构的指针,作为link访问列表中下一个元素的字段。

算法如下:

```

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

```

于 2018-05-23T14:03:32.290 回答
0
ll *rev_list(ll *prev, ll *cur)
{
    if (!cur) {
        return prev;
    }

    ll *tmp = cur;
    cur = cur->next;
    tmp->next = prev;
    prev = tmp;
    return rev_list(prev, cur);
}

查找完整代码:https ://github.com/vijaythreadtemp/Data-Structures-And-Algorithms/blob/master/rev_link_list_rec.cxx

于 2020-05-07T07:01:54.673 回答