这是C中的链表实现。
https://www.tutorialspoint.com/data_structures_algorithms/linked_list_program_in_c.htm
struct node { int data; int key; struct node *next; };
链表中的键是什么?在我看来,关键是节点的另一个数据。有钥匙有什么意义?
答案 0 :(得分:2)
它没有特殊用途(在链接列表实现的情况下)只是它被赋予了名称key
并存储了int
。正如你所说的那样,另一段数据与特定的实现相关(也许)。
变量名称似乎误导了我们它是一个关键或类似的东西,但事实并非如此。我们可以为其命名abc
,data2
或您能想到的任何可读名称。
正如 greenshade 所指出的,它用于使用链表建模字典。
答案 1 :(得分:1)
链表是一种类似链的数据结构,其中链中的每个“节点”包含一些数据,并且可选地链接到下一个节点,或者如果它是最后一个节点则根本不包含任何内容。用图形表示:
________ ________
| | | |
| Node A |---------->| Node B |--+
|________| |________| |
| | | | |
| 1 | | 2 | |
|________| |________| |
|
|
+--------------------------------+
| _______
+->| |
| Node C |
|________|
| |
| 42 |
|________|
列表中的第一个节点是A,最后一个ndoe是C.除最后一个节点外,所有节点都指向链中的下一个节点。概念本身我很简单。您可以使用以下代码在C中实现此链:
struct node
{
int data;
struct node* next;
};
typedef struct node* linked_list;
struct node node_c = { 42, NULL };
struct node node_b = { 2, &node_c };
struct node node_a = { 1, &node_b };
现在,您可能已经注意到,您描述的数据结构与此有点不同。具体地说,每个节点都有一个名为key
的额外字段。这很可能是为了实现地图和链表的低效并置,这将作为一种效率低下的字典。我提到它效率低下(这不是开玩笑,在实践中不要这样做)?这很可能是原始代码试图做的事情:
struct node
{
int key;
int data;
struct node* next;
};
typedef struct node* map;
map map_insert
(
map* the_map,
int key,
int data
)
{
map previous_node = NULL;
map current_node = *the_map;
while( current_node != NULL && current_node->key < key )
{
previous_node = current_node;
current_node = current_node->next;
}
map target_node;
if( current_node == NULL )
{
assert( target_node = malloc( sizeof( struct node ) ) );
target_node->key = key;
target_node->next = NULL;
} else if( current_node->key > key )
{
assert( target_node = malloc( sizeof( struct node ) ) );
target_node->key = key;
target_node->next = current_node;
} else
{
target_node = current_node;
}
if( previous_node != NULL )
{
previous_node->next = target_node;
} else
{
*the_map = target_node;
}
target_node->data = data;
}
int* map_find
(
map* the_map,
int key
)
{
map current_node = *the_map;
while( current_node != NULL && current_node->key < key )
{
current_node = current_node->next;
}
return current_node != NULL && current_node->key == key ? ¤t_node->data : NULL;
}
void map_remove
(
map* the_map,
int key
)
{
map previous_node = NULL;
map current_node = *the_map;
while( current_node != NULL && current_node->key < key )
{
previous_node = current_node;
current_node = current_node->next;
}
if( current_node == NULL || current_node->key > key )
{
return;
}
map next_node = current_node->next;
free( current_node );
if( previous_node != NULL )
{
previous_node->next = next_node;
} else
{
*the_map = next_node;
}
}
void map_new
(
map* the_map
)
{
*the_map = NULL;
}
void map_free
(
map* the_map
)
{
map current_node = *the_map;
while( current_node != NULL )
{
map next_node = current_node->next;
free( current_node );
current_node = next_node;
}
*the_map = NULL;
}
void do_pass
(
map* the_map,
unsigned pass
)
{
printf( "-- PASS %u --\n", pass );
map current_node = *the_map;
while( current_node != NULL )
{
printf( "%d -> %d\n", current_node->key, current_node->data );
current_node = current_node->next;
}
}
int main()
{
map my_map;
map_new( &my_map );
map_insert( &my_map, 0, 1 );
map_insert( &my_map, 1, 2 );
map_insert( &my_map, 2, 42 );
do_pass( &my_map, 1 );
map_insert( &my_map, 2, 3 );
map_remove( &my_map, 0 );
do_pass( &my_map, 2 );
*map_find( &my_map, 1 ) = 5;
do_pass( &my_map, 3 );
map_free( &my_map );
}
输出:
-- PASS 1 --
0 -> 1
1 -> 2
2 -> 42
-- PASS 2 --
1 -> 2
2 -> 3
-- PASS 3 --
1 -> 5
2 -> 3