#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
struct student
{
int ID;
int age;
struct student *next;
};
struct student *head = 0;
struct student *first = 0;
struct student *temp = 0;
void create_list()
{
static int counter = 1;
head = (struct student *)malloc(sizeof(struct student));
printf("Enter the student no. %d IDn",counter);
scanf_s("%d", &head->ID);
printf("Enter the student no. %d agen", counter);
scanf_s("%d", &head->age);
if (first != 0)
{
temp->next = head;
temp = head;
}
else
{
first = temp = head;
}
counter++;
}
void read_list()
{
temp->next = 0;
temp = first;
int counter = 1;
first = 0;
while (temp != 0)
{
printf("------------------Node number : %d---------------n", counter);
printf("The Student id is : %dn", temp->ID);
printf("The Student age is : %dn", temp->age);
counter++;
temp = temp->next;
}
printf("NULLn");
printf("-------------No. of nodes in the list = %dn------------------", counter);
}
void delete_list(struct student **head, int position)
{
if (*head == NULL)
return;
struct student* temp = *head;
if (position == 0)
{
*head = temp->next;
temp = 0;
return;
}
for (int i = 0; temp != NULL && i<position - 1; i++)
temp = temp->next;
if (temp == NULL || temp->next == NULL)
return;
struct student *next = temp->next->next;
temp->next=0;
temp->next = next;
}
void main()
{
int choice = 0;
while (choice != 99)
{
printf("Please enter a choice from the list:n");
printf("1- Create Noden");
printf("2- Read Listn");
printf("3- Delete Noden");
printf("99- Exitn");
scanf_s("%d", &choice);
switch (choice)
{
case 1:
create_list();
break;
case 2:
read_list();
break;
case 3:
delete_list(&head,2);
break;
}
}
}
我的删除功能遇到了很多问题。我正在创建一个链接节点列表。我创建了read-and-create函数,但每当我试图删除一个节点并移回所有节点时,它都会返回一个错误。我能得到一些关于哪里出了问题的帮助吗?
错误在于,每当我再次来打印列表时,它就会停止,什么都不打印。
如果还有任何问题,请联系我。祝你好运
关于createlist()
Head应该指向列表的第一个元素,但您使用Head来实例化添加到列表中的最新元素。第一和头在概念上是一样的。我认为你认为头部应该是列表中的最后一个元素,但它不应该。阅读有关链接列表的更多信息。你也从温度指向头部?等等,什么是温度?你能告诉我在你的程序中,那个时候的温度是多少吗?你不应该依赖temp,这就是它被称为temp的原因。它应该是一个时间变量。不是全局变量
关于read_list()
为什么temp->next=0?因为我们不知道什么是温度,你可能会在这里打破你的链条。让我们继续。因此,您指向列表中的第一个元素(应该与head相同)。天啊!您首先指向null。当然,你不能把清单读两遍或三遍。一旦你首先指向null,你就失去了对列表第一个元素的唯一引用。你对其他功能做什么并不重要。您将无法连续调用此函数两次,并且您的代码将中断
我的意思是。你第一次通过考试就先考临时工。然后第一个=NULL
第二次。temp=第一个。Buut。。。first=null?按门铃?您将无法打印任何其他内容
while循环正常。
关于delete_list()
好吧,你把我丢在这里了。你现在正在使用头部。但我可以告诉你,head绝对不是指向列表中的第一个元素。如果有什么不同的话,它是列表上的最后一个元素,并且(head->next=random stuff),如果幸运的话(head->next=null)。我不确定,但如果head指向列表上的第一个元素(但不是),这个函数可能可以或接近可以。但不要相信我的话,我现在真的很累
摘要:
您的功能错误。没有一个函数破坏了您的代码,而是有许多函数破坏了代码。你的主要问题是你用指针把事情搞砸了。如果我是你,我会:
- 删除first和temp作为全局变量
- 查看链接列表链接列表
- 在函数中使用temp作为局部变量
- 释放分配的内存,如果可能的话,在分配时检查错误
- 头应始终指向列表中的第一个元素。除非将第一个元素添加到列表中或删除最后一个元素,否则不应该更新head
- 你应该更新head的唯一情况是在列表的开头添加一个元素,但我鼓励你先尝试制作没有这个功能的程序
如果分配内存(例如,calloc或malloc),则应始终释放该内存并将指针指向NULL(这是一种很好的做法)。你编程的方式正在泄露内存。
此外,您不应该将temp作为全局变量。如果你不使用它,它可能会产生你不会遇到的问题。此外,有三个全局变量会使审查或调试变得更加困难。当你应该拥有的唯一全局变量是head时。
如果你想检查,我为你的代码写了一个替代方案。
代码说明:
我不检查用户输入,但它可以很容易地添加到主功能中。有5个函数:addLastElement、addFirstElement、deleteList、deleteElement和readList
-
readList:打印列表。
-
addLastElement:如果没有元素,它将添加头。如果有是元素,它将在列表的末尾添加一个新元素。它除非head为null,否则不会更新head。
-
addFirstElement:在列表的开头添加一个元素。这函数总是更新头部。
-
deleteElement:删除作为参数传递的位置中的元素。它释放了内存。
-
deleteList:将从列表中删除所有元素,并释放记忆力
除了readList之外的所有函数都会相应地更新结构列表的变量"size"。
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
struct student
{
int id;
int age;
struct student *next;
};
struct list
{
struct student *head;
int size;
};
void addFirstElement(struct list *list, int id, int age)
{
struct student *temp;
temp = (struct student *)malloc(sizeof(struct student));
if (temp == NULL)
{
printf("Error: Couldn't allocate memoryn");
}
temp -> id = id;
temp -> age = age;
temp->next = list -> head;
list->head = temp;
list->size++;
}
void addLastElement(struct list *list, int id, int age)
{
struct student *new;
struct student *temp;
new = (struct student *)malloc(sizeof(struct student));
if (new == NULL)
{
printf("Error: Couldn't allocate memoryn");
}
new->id = id;
new->age = age;
new->next = NULL;
if (list->head == NULL)
{
list->head = new;
}
else
{
temp = list -> head;
while (temp->next != NULL)
{
temp = temp->next;
}
temp->next = new;
}
list->size++;
}
void readList(struct list *list)
{
struct student *temp = list->head;
while (temp != NULL)
{
printf("ID: %d - Age: %dn", temp->id, temp->age);
temp = temp->next;
}
}
void deleteList(struct list *list)
{
struct student *temp;
struct student *previous;
temp = list->head;
while (temp != NULL)
{
previous = temp;
temp = temp->next;
free(previous);
}
previous = NULL;
list->size = 0;
list->head = NULL;
}
void deleteElement(struct list *list, int position)
{
if (list->head == NULL)
return;
if (position < 0 || position > ((list->size) - 1))
{
printf("The list is not that bign");
return;
}
struct student *temp = list->head;
struct student *previous = NULL;
int i = 0;
temp = list->head;
while (i != position)
{
previous = temp;
temp = temp->next;
i++;
}
if (previous == NULL)
{
list->head = list->head->next;
}
else
{
previous->next = temp->next;
}
list->size--;
free(temp);
temp = NULL;
return;
}
int main()
{
struct list list;
int i;
list.size = 0;
list.head = NULL;
for (i = 0; i < 10; i++)
{
addLastElement(&list, i, (i+1)*10);
}
deleteElement(&list, 5);
addFirstElement(&list, 100, 50);
readList(&list);
deleteList(&list);
return 1;
}
输出:
ID: 100 - Age: 50
ID: 0 - Age: 10
ID: 1 - Age: 20
ID: 2 - Age: 30
ID: 3 - Age: 40
ID: 4 - Age: 50
ID: 6 - Age: 70
ID: 7 - Age: 80
ID: 8 - Age: 90
ID: 9 - Age: 100
create_list()
中的代码不会检查内存分配是否成功。它也不能可靠地设置next
元素。这意味着,如果添加5个节点并打印它们,则只能看到列表中最近添加的节点。由于列表构造不正确,您的删除代码不太可能工作(对我来说它崩溃了,我也懒得弄清楚确切的原因;这可能是因为取消了对空指针的引用)。一个关键问题是head
和first
的角色混淆——first
确实指向列表的第一个元素,但从未更新,而head
也没有指向列表中的第一个元件,这与正常惯例相反。正如在评论中已经指出的,temp
主要令人困惑——它不应该作为全局变量存在。这是造成你问题的一个主要因素。
这里有一个替代实现。它不提示输入;它是硬连线添加5个学生,然后删除他们所有。它使用head
作为指向列表中第一个结构的单个全局变量。它在列表的开头添加新元素。它在添加或删除每个学生后打印列表,以便进行完整的检查。打印时,每个学生使用一行。当学生被删除时,它会释放内存。
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
struct student
{
int ID;
int age;
struct student *next;
};
struct student *head = 0;
static void create_list(int ID, int age)
{
struct student *node = (struct student *)malloc(sizeof(struct student));
if (node == 0)
{
fprintf(stderr, "Failed to allocate %zu bytesn", sizeof(*node));
exit(EXIT_FAILURE);
}
node->ID = ID;
node->age = age;
node->next = 0;
if (head != 0)
node->next = head;
head = node;
}
static void print_list(void)
{
int counter = 0;
for (struct student *node = head; node != 0; node = node->next)
{
printf("-- Node %2d: ID = %.5d, age = %dn", ++counter, node->ID, node->age);
}
printf("-- No. of nodes in the list = %dnn", counter);
}
static void delete_list(int position)
{
int counter = 0;
struct student *node = head;
struct student *prev = 0;
while (node != 0 && ++counter != position)
{
prev = node;
node = node->next;
}
if (node == NULL)
return;
if (prev == NULL)
{
assert(node == head);
struct student *old = head;
head = head->next;
free(old);
}
else
{
assert(node != head);
prev->next = node->next;
free(node);
}
}
int main(void)
{
create_list(10102, 19);
print_list();
create_list(23147, 20);
print_list();
create_list(30001, 21);
print_list();
create_list(47721, 18);
print_list();
create_list(59286, 20);
print_list();
delete_list(2);
print_list();
delete_list(3);
print_list();
delete_list(2);
print_list();
delete_list(1);
print_list();
delete_list(1);
print_list();
return 0;
}
示例输出:
-- Node 1: ID = 10102, age = 19
-- No. of nodes in the list = 1
-- Node 1: ID = 23147, age = 20
-- Node 2: ID = 10102, age = 19
-- No. of nodes in the list = 2
-- Node 1: ID = 30001, age = 21
-- Node 2: ID = 23147, age = 20
-- Node 3: ID = 10102, age = 19
-- No. of nodes in the list = 3
-- Node 1: ID = 47721, age = 18
-- Node 2: ID = 30001, age = 21
-- Node 3: ID = 23147, age = 20
-- Node 4: ID = 10102, age = 19
-- No. of nodes in the list = 4
-- Node 1: ID = 59286, age = 20
-- Node 2: ID = 47721, age = 18
-- Node 3: ID = 30001, age = 21
-- Node 4: ID = 23147, age = 20
-- Node 5: ID = 10102, age = 19
-- No. of nodes in the list = 5
-- Node 1: ID = 59286, age = 20
-- Node 2: ID = 30001, age = 21
-- Node 3: ID = 23147, age = 20
-- Node 4: ID = 10102, age = 19
-- No. of nodes in the list = 4
-- Node 1: ID = 59286, age = 20
-- Node 2: ID = 30001, age = 21
-- Node 3: ID = 10102, age = 19
-- No. of nodes in the list = 3
-- Node 1: ID = 59286, age = 20
-- Node 2: ID = 10102, age = 19
-- No. of nodes in the list = 2
-- Node 1: ID = 10102, age = 19
-- No. of nodes in the list = 1
-- No. of nodes in the list = 0