分配节点(反转链表)

时间:2012-06-18 21:25:11

标签: c pointers linked-list nodes

我想写一个迭代和递归方式来反转链表。

不幸的是,在这两种情况下,我都遇到了类似的问题:我无法将一个节点的指针更改为另一个节点,而且在某些情况下,我在迭代列表时遇到了困难。例如,这是我的递归反向函数:

node *reverse(node *initial){
    node *prev = initial;
    node *nextNode;
    nextNode = (node *)malloc(sizeof(struct node));
    nextNode = initial->next;
    if(nextNode->next == NULL){
        return  prev;
    }
    else{
        nextNode = reverse(nextNode);
        nextNode->next = prev;
    }
}

nextNode = initial->next;使程序崩溃。我确信这段代码还有很多其他问题,虽然我很容易接受建议,如果它存在致命缺陷,我大多只是想解决这个错误,以便我可以自己调试其余的。在迭代版本中,崩溃程序的一些类似行是:

startA = startA->next; // startA is a node pointer
backNode = startB; // backNode and startB are both node pointers
backNode->data = frontNode->data; //both ints
frontNode->data = temp; //again both ints

根据要求,其余代码:

main(){
node *  start = buildList();
int i;
int nodeSize = sizeof(struct node);
reverse(start);
}

和buildList:

node *buildList(){
node *head = NULL;
node *second = NULL;
node *third = NULL;
node *fourth = NULL;
node *fifth = NULL;

head = (node *)malloc(sizeof(struct node));
second = (node *)malloc(sizeof(struct node));
third = (node *)malloc(sizeof(struct node));
fourth = (node *)malloc(sizeof(struct node));
fifth = (node *)malloc(sizeof(struct node));

head->data = 1;
head->next = second;

second->data  =2;
second->next = third;

third->data = 3;
third->next = fourth;

fourth->data =4;
fourth->next = fifth;

fifth->data = 5;
fifth->next = NULL;

return head;    
}

2 个答案:

答案 0 :(得分:3)

请注意,当您在nextNode->next语句中取消引用if时,您尚未检查nextNode == NULL

基本上你在做:

if (initial->next->next == NULL)

如果initial->next == NULL,会发生什么?这也是递归 base-case 的问题。

此外,您的malloc被浪费并导致内存泄漏:您为nextNode分配了一个新内存块,然后在为{{1}分配其他内容时丢失对该块的引用在下一行:nextNode此处不需要nextNode = initial->next;:您不是在列表中添加新节点,只是重新排列您拥有的节点。

实施递归时,请仔细考虑基础案例。使用您想要递归的代码来遍历列表到最后一个节点,然后使用malloc再次向后构建列表。你怎么知道你什么时候在列表的最后一个节点?这是你的基础案例,你的递归函数应该从那里开始。你能用你的函数参数来确定吗?

这与您当前的代码没有什么不同,但您发布的代码包含许多错误。

答案 1 :(得分:1)

以下是您的快速演练:

node *reverse(node *initial){

    if (initial is NULL)
        /* this is an empty list so return */
        return a null pointer;

    if (initial->next is NULL)
        /* this is the recursion base case under normal operation - one elem left */
        return initial;

    node *prev = initial;
    node *nextNode = initial->next;

    /* reverse the rest of the list starting at the next node */
    nextNode = reverse(nextNode);

    /* now just reverse the pointers */
    initial->next->next = prev;
    /*
     * but remember that prev->next still points to the wrong node,
     * we need to clear that 
     */
    prev->next = NULL;

    /* you were also missing the return case here */
    /* we want to keep track of the last element (the new head element) */
    /* keep passing this back up through the recursive steps */
    return nextNode;

}