【问题标题】:how to create a heterogeneous link list in c or c++如何在 C 或 C++ 中创建异构链接列表
【发布时间】:2011-12-07 18:45:56
【问题描述】:

一个可以容纳float、integer、character等数据和算法的链表应该很好,不是很复杂

我想创建一个带有指向后续节点的 void 指针的结构。但问题是我不能使用有结构的模板。

回到c,我必须测试用户输入的每个字符以测试它是否是整数,浮点数或字符。然后我们可以继续进行

请提出一个有效的算法/代码

【问题讨论】:

  • boost::variant的链表怎么样
  • 为什么不能使用有结构的模板?
  • 它给出错误:未声明的结构!

标签: c++ c algorithm data-structures


【解决方案1】:

如果您想自己执行此操作,您基本上需要创建一个数组或元素的链接列表,这些元素对数据和数据类型进行编码。您可以使用包含类型指示符和要处理的各种类型的联合的结构,并创建该结构的数组或链表:

typedef struct {
    int type_indicator;
    union {
        float f;
        int i;
        double d;
        void *p;
        char c;
    }
} generic_item;

generic_item generic_array[10];

我会留给您为类型指示符提出适当的枚举并为您的算法添加函数指针。如果你想要一个链表而不是数组,你显然还需要添加一个generic_item *next 指针。

我没有研究过其他答案链接到的提升选项,但在尝试推出自己的解决方案之前,我可能会先看看那里。

【讨论】:

  • 您的想法已点击并触发了解决此问题的路径.. 谢谢
【解决方案2】:

使用boost::variantboost::any。取决于你的需要。

【讨论】:

    【解决方案3】:

    注意:这是一个纯粹的 C 答案。

    这个数据结构是我要开始的:

    typedef struct heterogeneous_list
    {
        enum { CHAR, STRING, FLOAT, INT } type;
        void *item;
        struct heterogeneous_list *next;
    }
    

    当我从用户那里得到项目时,我会将它存储在列表中(假设当前指向列表末尾):

    current->next = malloc(sizeof(heterogeneous_list));
    case (/* whether the user entered a char, string, float, or int */
    {
        case /* char */:
            current->next.item = malloc(sizeof(char));
            current->next.type = CHAR;
            current->next.next = NULL;
            break;
    /* and so forth, for string, int, and float */
    }
    current = current->next;
    

    当遍历列表时,现在很容易根据类型处理列表中的内容。下面的代码假定current 是列表中的当前项,正在迭代中查看(一个遍历列表的for循环):

    char currentItemChar;
    char * currentItemString;
    float currentItemFloat;
    int currentItemInt;
    
    case (current->type)
    {
        case CHAR:
            currentItemChar = *((char*) current->item);
            // process a character
            break;
        case STRING:
            currentItemString = (char*) current->item;
            // process a string
            break;
        case FLOAT: 
            currentItemFloat = *((float*) current->item);
            // process a float
            break;
        .
        .
        .
    };
    

    这就是我会做的。

    【讨论】:

    • @sbi,我没有得到你的评论,但仅供参考,这个问题也被标记为c
    • 大家,我在完成这篇文章之前不小心按了Enter。
    • @avakar:哎呀。这是对我的近距离投票的合理反对。我仍然不喜欢这个,但作为一个纯 C 的答案,它可能和它一样好。已删除反对票。 (不过,您可能想指出,这是一个 C 答案,但在您的答案的顶部。C/C++ 混合的答案通常会让公众根据他们来自的标签而投反对票。)
    【解决方案4】:

    http://www.boost.org/doc/libs/1_48_0/doc/html/variant.html

    (在解释提升变体为您提供什么之前,当然还提到了 C/C++ 联合)

    【讨论】:

      【解决方案5】:

      可以使用void *作为指向数据项的指针来创建异构链表:

      struct Node
      {
          Node * previous;
          Node * next;
          void * p_data;
      };
      

      在实现异构容器之前,人们可能会问是否可以将设计更改为使用同源容器。

      【讨论】:

      • 我尝试了一种方法,当您遍历链接列表时会出现问题。请考虑一下
      • @pravs:无论节点中的数据如何,遍历链表的方法都是一样的;实际上,节点中不需要有数据!
      • 我同意你的观点,但只有当链接列表的头部(开始)是一个空指针而不是 Node* 类型时才有可能
      • @pravs:链表的头部指向一个节点。它与节点内部的数据类型无关。
      【解决方案6】:

      可以使用-正如您所提到的-一些与一些或多或少棘手的宏相关的空指针来做这种事情。

      您可以定义一个包含三个指针的结构(或类):next、prev(用于下一个和上一个列表元素)和某种void* data。此外,您还可以存储每个列表条目的类型(可以通过 enum 或等效的东西来实现)。

      此外,您可以定义一个宏 - 给定一个列表项 - 检索数据并自动将其转换为给定类型:

      #define get_list_item(item, type) *(type*)(((item)->data))
      

      【讨论】:

        猜你喜欢
        • 2023-04-03
        • 1970-01-01
        • 1970-01-01
        • 2012-08-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多