我一般无法理解链接列表。我理解它们是如何在纸上工作的,但是一旦我对它们进行编码,我似乎永远不会做任何事情。
这是我的代码:
头文件:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef struct List {
int data;
struct List * next;
} List;
实施档案:
#include "test.h"
void addToFront(int data, List * head);
int main(void) {
List * list;
list = malloc(sizeof(List));
list->next = NULL;
List * head;
head = NULL;
addToFront(5,head);
printf("%d",head->data); //print first element
printf("%d",list->data); //print first element
}
void addToFront(int data, List * head) {
if(head == NULL) {
List * newNode = malloc(sizeof(List));
newNode->data = data;
head = newNode;
}
else {
List * newNode = malloc(sizeof(List));
newNode->data = data;
newNode->next = head;
head = newNode;
}
}
我知道如果链表是空的,标题是NULL
,所以我在那里检查过。问题出现了,因为我得到一个段错误说标题没有初始化,显然它不是,如果我做初始化,我无法跟踪列表是否为空,因此使用标题节点。
我现在能做什么?我不想使用双指针,至于我的班级到目前为止还没有其他人在使用它们(请不要让我使用双指针),我完全迷失了如何在这里继续。
我想在没有标题节点的情况下尝试这个。因此,我可以有一个计数器来跟踪列表中的项目,检查它是否为零,然后只是将基本元素添加到前面,否则我在我的else语句中做同样的事情?
答案 0 :(得分:0)
问题出在你的addFront函数中,你只需要将指针传递给头部,以便改变头部指向你需要传递头部地址的内容:
void addToFront(int data, List ** head)
然后
*head = newHead
当你只传递指针时,你只是将指针的副本传递给函数,所以一旦你离开函数范围,你在函数内做的指针的任何改变都会丢失。
概念类似于:
void f(int n)
{
n = 53;
}
为避免双指针,您可以返回新头:
List* addToFront(int data, List* head)
{
...
return newNode;
}
...
head = addToFront(data, head);
...
答案 1 :(得分:0)
如果您不想使用双指针,则可以将标头节点用作前哨节点,该节点仅用作占位符,以便第一个元素由head->next
链接,并且检查列表是否为空,请检查head->next == NULL
。试试这个:
int main(void) {
List *head = malloc(sizeof(List));
head->data = 0;
head->next = NULL;
addToFront(5, head);
List *first = head->next;
if (first) { // safe guard for first element
printf("%d", first->data); //print first element
printf("%d", first->data); //print first element
}
}
void addToFront(int data, List * head) {
List * newNode = malloc(sizeof(List));
newNode->data = data;
newNode->next = head->next;
head->next = newNode;
}