C 插入到链接列表中
我仍然在学习链表,并且一直在尝试创建一种方法来插入链表 我只是想知道这是不是正确的插入方式?另外,如何打印整个链接列表,使其打印类似于C 插入到链接列表中,c,C,我仍然在学习链表,并且一直在尝试创建一种方法来插入链表 我只是想知道这是不是正确的插入方式?另外,如何打印整个链接列表,使其打印类似于abc 以下是我所拥有的: struct node { char value; struct node *next; }; typedef struct node item; void main() { InsertChar('a'); InsertChar('b'); InsertChar('c'); } void In
abc
以下是我所拥有的:
struct node {
char value;
struct node *next;
};
typedef struct node item;
void main() {
InsertChar('a');
InsertChar('b');
InsertChar('c');
}
void InsertChar(char s) {
item *curr, *head;
head = NULL;
curr = (item *)malloc(sizeof(item));
curr->value = s;
curr->next = head;
head = curr;
while(curr) {
printf("%c\n", curr->value);
curr = curr->next;
}
}
首先,您的函数
InsertChar
每次都会覆盖head
的值(head=curr
),因此您将得到一个包含一项的列表
您需要声明将存储head
的内容
struct list
{
struct node *head;
};
现在,通过浏览每个节点
,您可以轻松打印列表
void PrintList(struct list* list)
{
struct node *curr = list->head;
while (curr != NULL)
{
printf("%c\n", curr->value);
curr = curr->next;
}
}
现在您需要修改
InsertChar
,以便列表中的最后一项(您将如何找到它?)指向您的新项。我将把它留给您:)您可能已经注意到,您无法从外部InsertChar()
访问列表(如果有)。您不使用全局变量,也不输入或输出它
更好的实施:
item * InsertChar(item ** phead, char s) {
item * curr;
// First, allocate a new item and fill it.
curr = malloc(sizeof(item)); // no need to cast here
if (curr) { // only if malloc() succeeds
curr->value = s;
curr->next = *phead;
*phead = curr;
}
return curr;
}
// InsertChar() is only supposed to insert, not to print.
void PrintList(item * head) {
item * curr = head;
while(curr) {
printf("%c", curr->value); // omit the line break as you want abc
curr = curr->next;
}
printf("\n"); // now the line break
return;
// alternative implementation for while loop:
for(curr=head; curr; curr=curr->next) {
printf("%c\n", curr->value);
}
}
void FreeList(item * head) {
item * curr = head;
while(curr) {
item * next = curr->next; // read it out before freeing.
free(curr);
curr = next;
}
}
这样你现在就可以做了
int main() {
item * list = NULL; // empty for now, no contents.
char success = 1;
success = success && InsertChar(&list, 'a');
success = success && InsertChar(&list, 'b');
success = success && InsertChar(&list, 'c');
if (!success) {
printf("Oops?");
FreeList(list);
return 1;
}
PrintList(list);
FreeList(list); // clean up.
}
哎呀?我没有测试它,但在我看来,它打印的是“cba”。为什么会这样?好吧,InsertChar()将一切从头开始
怎么避开这个
我们可以创建一个AppendChar()函数。但这承担着我们陷入陷阱的危险:总是从一开始就开始寻找正确的地方。因此,我将指出另一种方法:
int main() {
item * list = NULL; // empty for now, no contents.
item * cursor = InsertChar(&list, 'a');
if (!cursor) goto error;
// cursor now contains our first entry.
// We put the next one to cursor->next:
cursor = InsertChar(&cursor->next, 'b');
if (!cursor) goto error;
cursor = InsertChar(&cursor->next, 'c');
if (!cursor) goto error;
PrintList(list);
FreeList(list); // clean up.
return 0;
error:
printf("Oops?");
FreeList(list);
return 1;
}
我不确定我是否正确(没有测试),但这应该是一条路
如果您是其中一个被教导在任何情况下goto都是邪恶的人,请随意以不同的方式实现错误处理。您需要查看函数定义
void PrintList(struct list){…}
。您有一个类型struct list
,但没有变量名(在原型中是OK,在函数定义中不是OK)。您应该能够使用void PrintList(struct list*list){…}
,因为结构标记位于与普通变量名不同的命名空间中。