C 链接列表中的键是什么?

C 链接列表中的键是什么?,c,data-structures,linked-list,C,Data Structures,Linked List,下面是C语言中的链表实现 链接列表中的键是什么?在我看来,密钥只是节点的另一段数据。有钥匙有什么意义 在链表实现的情况下,它没有特殊用途,只是被赋予了名称键并存储了一个int。正如您所说的,它只是与特定实现相关的另一段数据 变量名似乎误导了我们,认为它是一个键或类似的东西,但事实并非如此。我们可以给它命名为abc、data2或任何你能想到的可读名称 正如greenshade所指出的,它用于使用链表为字典建模 在链表实现的情况下,它没有特殊用途,只是被赋予了名称键并存储了一个int。正如您所说的,

下面是C语言中的链表实现


链接列表中的键是什么?在我看来,密钥只是节点的另一段数据。有钥匙有什么意义

在链表实现的情况下,它没有特殊用途,只是被赋予了名称键并存储了一个int。正如您所说的,它只是与特定实现相关的另一段数据

变量名似乎误导了我们,认为它是一个键或类似的东西,但事实并非如此。我们可以给它命名为abc、data2或任何你能想到的可读名称


正如greenshade所指出的,它用于使用链表为字典建模

在链表实现的情况下,它没有特殊用途,只是被赋予了名称键并存储了一个int。正如您所说的,它只是与特定实现相关的另一段数据

变量名似乎误导了我们,认为它是一个键或类似的东西,但事实并非如此。我们可以给它命名为abc、data2或任何你能想到的可读名称


正如greenshade所指出的,它用于使用链表为字典建模

链表是一种链式数据结构,其中链中的每个节点都包含一些数据,并且可以选择链接到下一个节点,如果是最后一个节点,则根本不链接。用图形的方式说:

 ________             ________
|        |           |        |
| 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 ? &current_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 );
}

链表是一种类似于链的数据结构,其中链中的每个节点都包含一些数据,并且可以选择链接到下一个节点,如果是最后一个节点,则完全不链接。用图形的方式说:

 ________             ________
|        |           |        |
| 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 ? &current_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 );
}

键在这里用来建立一个带有链表的字典模型。只是另一段数据。对于链表数据结构来说,这不是工作所必需的,因为指向下一个节点的指针是。一般来说,没有点。这似乎只是为了说明,这里使用的是一个链接列表的字典模型,只是另一段数据。对于链表数据结构来说,这不是工作所必需的,因为指向下一个节点的指针是。一般来说,没有点。这似乎只是为了说明的目的,服务器没有特殊的目的引用一个普通的链表你是正确的,但是引用代码OP linked元素键很好地服务于一个特定的目的。另请参见。@alk.:啊,我们也可以把它命名为dictKey.。所以我说它只是一个变量名,可能是其他的东西…它与链表实现无关。@alk.:我编辑了它,这样就没有什么可混淆的了。谢谢你的指点。引用一个简单的链表没有什么特殊的用途。你是对的,但是引用代码OP链接元素键很好地服务于一个特定的用途。另请参见。@alk.:啊,我们也可以把它命名为dictKey.。所以我说它只是一个变量名,可能是其他的东西…它与链表实现无关。@alk.:我编辑了它,这样就没有什么可混淆的了。谢谢你指出。