我想写一个迭代和递归方式来反转链表。
不幸的是,在这两种情况下,我都遇到了类似的问题:我无法将一个节点的指针更改为另一个节点,而且在某些情况下,我在迭代列表时遇到了困难。例如,这是我的递归反向函数:
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;
}
答案 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;
}