反转列表会导致Seg错误

时间:2015-11-05 18:19:47

标签: c pointers recursion struct

我试图以递归方式反转链接列表。我有这些结构:

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的参数参数,我被告知我必须调用另一个函数,并使用那个作为递归调用函数(我有)。任何帮助将非常感激。

1 个答案:

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

Demo.

相关问题