我试图以递归方式反转链接列表。我有这些结构:
typedef Test test;
typedef struct Node {
test t;
struct Node *nxt;
} LNode;
typedef struct {
int size;
LNode *first;
} L;
其中Test是包含学生姓名和成绩的结构(考试成绩)。
void recursiveReverse(L * r) {
LNode * first;
first = r->first; //first node in list
reverseList(first);
}
void reverseList(LNode * first) {
LNode * rest;
rest = first->nxt;
reverseList(r,rest);
first->nxt->nxt = first;
first->nxt = NULL;
first = rest;
}
然而,在尝试此操作时,我似乎遇到了段错误。我不允许更改函数recursiveReverse
的参数参数,我被告知我必须调用另一个函数,并使用那个作为递归调用函数(我有)。任何帮助将非常感激。
答案 0 :(得分:1)
编写递归函数最重要的规则是它们必须终止。简单来说,必须存在递归函数不调用自身的条件。这就是所谓的"基本情况"。
对于列表反转函数,基本情况是当您必须反向的列表部分恰好包含一个节点时,因为单节点列表本身就是一个简单的反转。因此,reverseList
内部需要有一个案例,你可以这样说:
if (first->nxt == NULL) {
// Do not go into recursive invocation
return; // This is not complete yet
}
您的代码中缺少的另一件事是反向列表将有一个新的头,这是以前的节点。您的reverseList
应该退回。
编写其余递归函数的一个有用技巧是想象这个函数已经为你编写了,并且在知道它的情况下调用它,忘了片刻< em>如何它做到了。在列表反转的情况下,递归步骤相对容易:您获得反转列表的头部,然后将当前节点的下一个更改为指向当前节点。
LNode* reverseList(LNode* list) {
if (list->nxt == null) {
return list;
}
// Reverse the tail
LNode *head = reverseList(list->nxt);
// Invert this node
list->nxt->nxt = list;
// Return the result of tail reversal
return head;
}
此时唯一缺少的是将新尾nxt
设置为NULL
。您应该在recursiveReverse
函数中执行此操作:
void recursiveReverse(L * r) {
LNode *first = r->first;
LNode *newHead = reverseList(first);
first->nxt = NULL;
r->first = newHead;
}