出于某种原因,如果我有一个看起来像3-> 2-> 1-> 0的链表,我打电话给deleteSecond(head),我得到3-> 1-> 0-大于0。这是我的代码:
#include <stdio.h>
#include <stdlib.h>
typedef struct ListNode {
int data;
struct ListNode *next;
} *LinkedList;
int deleteSecond(LinkedList list) {
if (list == NULL || list->next == NULL)
return 0;
int val = list->next->data;
LinkedList second = list->next;
list->next = list->next->next;
free(second);
return val;
}
int main() {
LinkedList head = NULL;
head = malloc(sizeof(LinkedList));
for (int i = 0; i < 4; i++) {
LinkedList newNode = malloc(sizeof(LinkedList));
newNode->data = i;
newNode->next = head;
head = newNode;
}
LinkedList ptr = head;
for (int i = 0; i < 4; i++) {
printf("%d\n", ptr->data);
ptr = ptr->next;
}
printf("\n");
deleteSecond(head);
while (head != NULL) {
printf("%d\n", head->data);
head = head->next;
}
return 0;
}
我相信我的deleteSecond函数应该是正确的。我创建了一个指向我的第二个节点的指针,然后我将head-&gt; next = head-&gt; next-&gt; next,然后我将指针释放到第二个节点。我不知道为什么我在列表末尾有两个0。
答案 0 :(得分:2)
您正在创建一个正在创建问题的空节点NULL
。您的上一个节点应指向head = NULL
。因此,初始化 LinkedList head = NULL;
// head = malloc(sizeof(LinkedList));
for (int i = 0; i < 4; i++) {
LinkedList newNode = malloc(sizeof(LinkedList));
newNode->data = i;
newNode->next = head;
head = newNode;
}
是正确的。
{{1}}
答案 1 :(得分:1)
head = malloc(sizeof(LinkedList));
这是错误的。正确的是
head = malloc(sizeof(*head));
然后再次以同样的方式
LinkedList newNode = malloc(sizeof(*newNode));
现在让我们看看你在这里做了什么。
永远不会初始化 head
的数据或链接属性。因此,您将获得访问它的未定义行为。
如果要将内存分配给head
,这是您要编写的代码。
...
int main(void) {
LinkedList head = NULL;
head = malloc(sizeof(*head));
if( head == NULL){
fprintf(stderr, "%s\n","Error in malloc" );
exit(1);
}
head->next = NULL;
head->data = 2017; // dummy data.
for (int i = 0; i < 4; i++) {
LinkedList newNode = malloc(sizeof(*newNode));
if( newNode == NULL){
fprintf(stderr, "%s\n","Error in malloc" );
exit(1);
}
newNode->data = i;
newNode->next = head;
head = newNode;
}
...
...
deleteSecond(head);
while (head != NULL) {
printf("%d\n", head->data); // prints 2017 also. But deletes the node that was in second position.
head = head->next;
}
return 0;
}
这里我们使用了一个额外的节点来保存虚拟数据。是!它不需要。除了为newNodes
提供下一个链接之外,这个虚拟节点没有任何重要意义,如果您只使用head
作为LinkedList
或struct LinkedNode*
并且不分配任何内存它。它建议我们可以消除并简单地使用指向struct ListNode
的指针,即head
。
然后代码就像
LinkedList head = NULL;
for (int i = 0; i < 4; i++) {
LinkedList newNode = malloc(sizeof(*newNode));
if( newNode == NULL){
fprintf(stderr, "%s\n","Error in malloc" );
exit(1);
}
newNode->data = i;
newNode->next = head;
head = newNode;
}
您可以考虑几件事
malloc
。代码也可以这种方式编写。它不使用typedef
下的指针并模块化可重用代码。
#include <stdio.h>
#include <stdlib.h>
typedef struct ListNode {
int data;
struct ListNode *next;
} ListNode;
void freeMemList(ListNode *head){
ListNode *temp;
while(head!=NULL){
temp = head;
head = head->next;
free(temp);
}
}
int deleteSecond(ListNode * list) {
if (list == NULL || list->next == NULL)
return 0;
int val = list->next->data;
ListNode * second = list->next;
list->next = list->next->next;
free(second);
return val;
}
void printList(ListNode *head){
while (head != NULL) {
printf("%d\n", head->data);
head = head->next;
}
}
struct ListNode * addNodes(struct ListNode* head, int n){
for (size_t i = 0; i < n; i++) {
ListNode * newNode = malloc(sizeof(*newNode));
if( newNode == NULL){
fprintf(stderr, "%s\n","Error in malloc" );
exit(1);
}
newNode->data = i;
newNode->next = head;
head = newNode;
}
return head;
}
int main(void) {
ListNode * head = NULL;
head = addNodes(head,4);
printList(head);
printf("********\n");
int valDeleted = deleteSecond(head);
printf("%s %d\n","Value deleted ", valDeleted );
printList(head);
freeMemList(head);
return 0;
}