我正在尝试使用递归来反转链接列表并为其编写以下代码。列表是开头的列表的开头。
node *reverse_list_recursive(node *list)
{
node *parent = list;
node *current = list->next;
if(current == NULL)
return parent;
else
{
current = reverse_list_recursive(current);
current->next = parent;
printf("\n %d %d \n",current->value,parent->value);
return parent;
}
}
我可以看到所有链接都被颠倒了。然而,当我尝试显示时,我得到了数字的无限打印。当我试图反转列表中最初的第一个数字的链接时,我怀疑是错误的。
我做错了什么?
答案 0 :(得分:5)
假设我有一个链表:
---------- ---------- ---------- ----------
| 1 | |--->| 2 | |--->| 3 | |--->| 4 | |--->NULL
---------- ---------- ---------- ----------
您的代码将其转换为:
---------------------- ----------------------
| | | |
v | v |
---------- ---------- ---------- ----------
| 1 | |--->| 2 | | | 3 | | | 4 | |
---------- ---------- ---------- ----------
^ |
| |
----------------------
请注意,第一个元素仍然指向2。
如果在前两个之后添加行parent->next = NULL
,您将获得:
---------------------- ----------------------
| | | |
v | v |
---------- ---------- ---------- ----------
NULL<---| 1 | | | 2 | | | 3 | | | 4 | |
---------- ---------- ---------- ----------
^ |
| |
----------------------
实际上是正确的结构。
完整的代码是:(您只需要为每个递归调用打印当前值)
node *reverse_list_recursive(node *list)
{
node *parent = list;
node *current = list->next;
if(current == NULL)
return parent;
else
{
current = reverse_list_recursive(current);
parent->next = NULL;
current->next = parent;
printf("\n %d \n",current->value);
return parent;
}
}
答案 1 :(得分:2)
您需要将新尾部(即旧头部)的下一个指针设置为NULL
编辑:这是一个递归版本
node *reverse_list_recursive(node *list)
{
node *parent = list;
node *child = list->next;
node *new_head;
if (child == NULL)
return parent ; /* new head */
new_head = reverse_list_recursive(child)
child->next = parent; /* Old parent is the new child of the old child when reversed */
parent->next = NULL; /* might be tail, will be overwritten after we return if we're not at the top level */
return new_head;
}
答案 2 :(得分:2)
当您到达列表末尾时,将返回最后一个节点。然后,最后一个节点的下一个值被分配给自己,因此您会产生不一致。如果current为NULL,则返回NULL,如果返回为NULL,则忽略其余代码。
答案 3 :(得分:2)
您忘记更新链接列表中第一个项目的next
成员。在递归调用之前添加parent->next = NULL;
。
答案 4 :(得分:2)
我没有看到递归的好处,迭代也会起作用。自从我编写C(并且没有简单的方法来测试以下语法错误......或者 cringe 核心转储,但你得到了这个想法)以来,它一直是永恒的。
node *reversed_list(node *list) {
node *fwd=list;//Purely for readability
node *last=null;
node *next=null;
node *rev=null;
do {
//Cache next
next=fwd->next;
//Set current
rev=fwd;
//Reset next to point back
rev->next=last;
//Update last
last=fwd;
//Forward ptr;
fwd=next;
} while (fwd!=null);
return rev;
}
非常确定你的*list
在调用之后没用,因为它现在指向列表的最后一个元素->next=null
,可能只是更新它而不是返回指针。
更新(针对递归解决方案)
正如其他人所说,你的新尾巴搞砸了(指向最后一个元素,但应该指向null)......并且你没有返回正确的头部,你返回第二个元素。请考虑使用您的算法列表a->b->null
:
p=a, c=b; c= p=b c=null return b; //b->null c=b c->next=a //b->a return a; //a->b, b->a, a returned //But what you wanted is a->null, b->a, and b returned
以下更新的代码将会修复:
node *reverse_list_recursive(node *list)
{
node *parent = list;
node *current = list->next;
if(current == NULL)
return parent;
else
{
current = reverse_list_recursive(current);
current->next = parent;
parent->next=null; //Fix tail
printf("\n %d %d \n",current->value,parent->value);
return current; //Fix head
}
}
使用列表a->b->null
:
p=a, c=b; c= p=b c=null return b; //b->null c=b c->next=a //b->a p->next=null //a->null return b; // b->a->null
答案 5 :(得分:1)
在行current = reverse_list_recursive(current);
之后,您将新列表头存储在当前,因此current->next = parent;
是错误的。新的current
是新的列表头,但您需要访问新的列表尾部,即OLD current
:
node* newhead = reverse_list_recursive(current);
current->next = parent;
printf("\n %d %d \n",current->value,parent->value);
return newhead;
答案 6 :(得分:1)
我可以看到的一些问题:
答案 7 :(得分:1)
这里是用于反转链表的递归代码。
list * reverse(list * head)
{
if( head == NULL || head -> link == NULL )
return head;
list *node = reverse( head- > link );
head -> link -> link = head;
head -> link = NULL;
return node;
}
答案 8 :(得分:0)
上面的Severl版本不能像OP那样工作,所以这里我的递归版测试很好:
node * reverseRecursive(node *p,node **head)
{
if(p->next == NULL)
{
*head = p;
return p;
}
node *before;
before = reverseRecursive(p->next,head);
before->next = p;
p->next = NULL;
return p;
}
//call from main
node*head;
//adding value
//assuming now head is now 1->2->3->4->NULL
node* newHead;
reverseRecursive(head,&newHead);
//now now newHead is now 4->3->2->1->NULL
答案 9 :(得分:0)
不同的代码如下:
'
#include <stdio.h>
#include <stdlib.h>
#pragma warning(disable:4996)
struct Node {
int data;
struct Node* next;
};
typedef struct Node node;
node* dogrusıralama(node* r)
{
for (int i = 0; i < 6; i++)
{
printf("%d", r->data);
r = r->next;
printf("\n");
}
}
node *terssıralama(node* r)
{
node* iter;
iter = r;
node* temp;
temp = r;
node* temp2;
temp2 = r;
int a = 4;
for (int k = 0; k < 5; k++)
{
temp2 = temp2->next;
}
for (int j = 0; j < 5; j++)
{
int i = a;
for (; i > 0; i--)
{
temp = temp->next;
}
a--;
iter = temp;
iter->next->next = iter ;
temp = r;
}
temp->next = NULL;
return temp2;
}
int main() {
node* dugum;
node* dugum2;
node* dugum3;
node* dugum4;
dugum = (node*)malloc(sizeof(node*));
dugum2 = dugum;
for (int i = 0; i < 5; i++)
{
dugum2->next = NULL;
dugum2->next = (node*)malloc(sizeof(node*));
dugum2->data = i;
dugum2 = dugum2->next;
}
dugum4 = dugum;
dogrusıralama(dugum);
dugum3 = terssıralama(dugum);
for (int i = 0; i < 6; i++)
{
printf("\n");
printf("%d", dugum3->data);
dugum3 = dugum3->next;
}
} '