编写器(以及每个教程中的所有其他编码器)将创建节点类型指针变量,然后使用typecasting和malloc为它们分配内存。这对我来说似乎是不必要的(当然,我知道我缺少什么),为什么我们不能使用此实现相同的东西?
struct node
{
int data;
struct node *next;
};
int main()
{
struct node head;
struct node second;
struct node third;
head.data = 1;
head.next = &second;
second.data = 2;
second.next = &third;
third.data = 3;
third.next = NULL;
getchar();
return 0;
}
我已经创建了节点,下一个指针指向下一个节点的地址...
假设您创建了一个类型node
为的变量my_node
:
struct node my_node;
您可以按my_node.data
和访问它的成员,my_node.next
因为它不是指针。但是,您的代码将只能创建3个节点。假设您有一个循环,要求用户输入一个数字并将该数字存储在链接列表中,仅当用户键入0时才停止。您不知道用户何时键入0,因此必须有一个程序运行时创建变量的方法。在运行时“创建变量”称为动态内存分配,并通过调用来完成malloc
,该调用始终返回一个指针。不要忘记释放不再需要的动态分配数据,为此,请free
使用由返回的指针来调用该函数。malloc
。您提到的教程仅说明了链表的基本概念,在实际程序中,您不会将自己限制为固定数量的节点,而是根据仅在运行时拥有的信息来调整链表的大小(除非您只需要一个固定大小的链表)。
编辑:
“在运行时创建变量”只是解释指针需求的一种高度简化的方式。调用时malloc
,它将在堆上分配内存并为您提供一个地址,该地址必须存储在指针中。
int var = 5;
int * ptr = &var;
在这种情况下,ptr
是一个变量(已在所有功能中声明),它包含另一个变量的地址,因此称为指针。现在考虑您提到的教程的摘录:
struct node* head = NULL;
head = (struct node*)malloc(sizeof(struct node));
在这种情况下,变量head
将指向运行时在堆上分配的数据。
如果您继续在堆上分配节点,并将返回的地址分配给next
链表中最后一个节点的成员,则只需编写即可遍历链表pointer_to_node = pointer_to_node->next
。例:
struct node * my_node = head; // my_node points to the first node in the linked list
while (true)
{
printf("%d\n", my_node->data); // print the data of the node we're iterating over
my_node = my_node->next; // advance the my_node pointer to the next node
if (my_node->next == NULL) // let's assume that the 'next' member of the last node is always set to NULL
{
printf("%d\n", my_node->data);
break;
}
}
当然,您可以将元素插入到链表的任何位置,而不仅仅是如上所述。请注意,尽管您唯一的名称节点是head
,但其他所有节点都可以通过指针进行访问,因为您无法命名程序将拥有的所有节点。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句