链接到底指向哪里?
link 指向另一个相同类型的对象:
+------+------+ +------+------+ +------+------+
| data | link |---->| data | link |---->| data | link | ----> ...
+------+------+ +------+------+ +------+------+
现在在结构List中,head在做什么?它指向什么?
head 指向列表中的第一个节点:
+-----------------+ +------+------+ +------+------+
| head |---->| data | link |---->| data | link |----> ...
+-----------------+ +------+------+ +------+------+
| number_of_nodes |
+-----------------+
我真的在尽我最大的努力去理解链表是如何工作的,
别难过——链表让我在我的数据结构类(我的第一个“硬”CS 类)中陷入了循环。我比我的同学花了整整一周的时间来理解这个概念。希望图片有所帮助。
编辑
如果你有一个指向结构列表、分配的内存等等的指针会发生什么?那么它指向哪里(根据图表,顺便说一句确实有帮助)
所以,假设您有以下代码:
/**
* Create a new list object. head is initially NULL,
* number_of_nodes initially 0.
*/
List *newList( void )
{
List *l = malloc( sizeof *l );
if ( l )
{
l->head = NULL;
l->number_of_nodes = 0;
}
return l;
}
int main( void )
{
List *l = newList();
...
}
那么你的图片是这样的:
+---------+ +--------------------+
| l: addr | ----> | head: NULL |
+---------+ +--------------------+
| number_of_nodes: 0 |
+--------------------+
(addr代表任意内存地址)
现在假设您将一个节点添加到列表中:
/**
* Create a new node object, using the input data
* link is initially NULL
*/
Node *newNode( int data )
{
Node *n = malloc( sizeof *n );
if ( n )
{
n->data = data;
n->link = NULL;
}
return n;
}
void insertNode( List *l, int data )
{
Node *n = newNode( data );
if ( n )
{
/**
* If list is initially empty, make this new node the head
* of the list. Otherwise, add the new node to the end of the
* list.
*/
if ( !l->head ) // or n->head == NULL
{
l->head = n;
}
else
{
/**
* cur initially points to the first element in the list.
* While the current element has a non-NULL link, follow
* that link.
*/
for ( Node *cur = l->head; cur->link != NULL; cur = cur->link )
; // empty loop body
cur->link = n;
}
l->number_of_nodes++;
}
}
int main( void )
{
List *l = newList();
insertNode( l, 5 );
...
}
现在你的图片是这样的:
+---------+ +--------------------+ +------------+
| l: addr | ----> | head: addr | ---> | data: 5 |
+---------+ +--------------------+ +------------+
| number_of_nodes: 1 | | link: NULL |
+--------------------+ +------------+
您可以添加另一个节点:
int main( void )
{
List *l = newList();
insertNode( l, 5 );
insertNode( l, 3 );
...
}
那么你的图片就变成了
+---------+ +--------------------+ +------------+ +------------+
| l: addr | ----> | head: addr | ---> | data: 5 | +--> | data: 3 |
+---------+ +--------------------+ +------------+ | +------------+
| number_of_nodes: 2 | | link: addr | --+ | link: NULL |
+--------------------+ +------------+ +------------+
当然,您会想要添加一些错误检查和消息,以防无法分配节点(发生这种情况)。您可能需要一个有序列表,其中元素按顺序插入(升序、降序等)。但这应该让您了解如何构建列表。
您还需要删除项目并释放内存的函数。以下是我如何释放整个列表:
void freeList( List *l )
{
Node *prev, *cur = l->head;
while( cur && cur->link )
{
prev = cur;
cur = cur->link;
free( prev );
}
free( cur );
}
int main( void )
{
List *l = newList();
...
freeList( l );
free( l );
...
}