【问题标题】:What is a linked list that defines no data storage called? [closed]什么是未定义数据存储的链表? [关闭]
【发布时间】:2011-10-30 04:11:18
【问题描述】:

我在 C 中使用单链表,没有指向节点值的指针。所以,而不是:

struct _node 
{
  struct _node * next;
  void* value;
} node;

我有

struct _node 
{
   struct _node * next;
} node;

这样的列表有特殊名称吗?

编辑:

只是为了解释为什么这些列表很有用(我真的不明白为什么反对票):

struct 
{
  node node;
  int i;
} s;

当我这样做时,我强制 struct s 有一个节点,但不必设置 void* 值。

我正在使用这个方案来保存我的任务信息,这些信息将在 FIFO 列表中。

【问题讨论】:

  • 是的,这将是一个“毫无意义的列表”,如前所述。是的,我有一个连接的列表......什么都没有。多么有用...
  • 它们的主要优点是在任何位置插入任何内容的复杂度都是 O(1)。另一方面,零长度数组仍然更好,因为它们需要零时间来插入任何内容。
  • 您的意思是 _node 实际保存其他数据的位置,而不是指向该数据的指针?
  • @Matteo:不正确,如果您必须搜索节点,则不是 O(1)。如果您不必搜索,那么对于普通链表来说也是 O(1)。顺便说一句,节点实际上是有身份的,所以例如对于任何节点,都有一个隐含的属性:有多少个节点直到尾部。
  • 这样的数据结构的要点是,实际数据存储在距节点结构的固定偏移处(例如,作为malloc获得的同一块的一部分),而不是指向由节点。 Linux 在内核空间中到处都使用这个原则,甚至有很好的宏来处理这些列表。

标签: c list pointers nomenclature


【解决方案1】:

我认为 C 程序员只是将其称为“链表”,并将其视为链表的“正常”形式。只有在鼓励更多臃肿习语的语言中,在列表节点中包含指向数据的指针,而不是仅仅将节点和数据存储在一起,才是常态。

【讨论】:

    【解决方案2】:

    您是在谈论将“列表机制”移动到单独的结构:

    struct Single_Link;
    struct Single_Link
    {
        Single_Link * next;
    };
    

    从上面的结构可以推导出:

    struct Double_Link_Node
    : public Single_Link_Node
    {
        Single_Link * previous;
    };
    

    使用上面的结构,可以定义一个通用节点:

    template <class Value_Type>
    struct Node_Contains_Value
    : public Single_Link
    {
        Value_Type value;
    };
    

    或者您可以使用指向值的通用指针:

    struct Node_Contains_Pointer
    : public Single_Link
    {
        void * pointer_to_value;
    };
    

    链表会维护一个指向第一个节点的指针:

    template <class Value_Type>
    struct Linked_List
    {
        Node_Contains_Value * ptr_to_head_node;
        Node_Contains_Value * ptr_to_last_node;
    };
    

    如果这不是家庭作业,我强烈建议使用std::list,因为它已经过彻底测试。

    【讨论】:

    • 我正在使用 C。clib 也有列表吗?我找不到一个
    【解决方案3】:

    例如,这就是 linux 内核实现链表的方式。查看 linklink 或许多其他描述其链表实现的人

    至于您的实际问题,我认为该模式没有实际名称。这只是在 C 中创建通用链表的一种方式。

    【讨论】:

      【解决方案4】:

      我不确定它是否有名称。它仍然是构建链表的有用方法,因为您可以将链接与数据放在一起,但仍将两者分开。

      typedef struct _payload
      {
          int x;
          double y;
          char * z;
      } payload;
      
      struct _node * pNode;
      payload * pData;
      pNode = malloc(sizeof(struct _node)+sizeof(payload));
      pData = (payload *)(((char*)p)+sizeof(struct _node));
      

      【讨论】:

      • 我不确定 OP 是否真的要求这个东西,这实际上是一个伪装的“正常”链表......不过,+1 是为了找到这样一个东西的合理用途。
      • 此技术用于Windows interlocked singly-linked list API,其中结构称为SLIST_ENTRY
      • @Matteo,有时您必须在字里行间阅读。我真的希望这是他们所要求的。
      • @Mark:这就是我给你 +1 的原因 :)
      • @Mark:我会谨慎使用该代码,因为您不会对有效负载的对齐方式进行任何检查。我宁愿看到类似struct payload { int x; double y; struct _node node; }; 的东西,然后使用一些CONTAINER_OF 宏。
      猜你喜欢
      • 2020-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多