如何在c或c ++中创建异构链接列表

时间:2011-12-07 18:45:57

标签: c++ c algorithm data-structures

一个可以保存浮点数,整数,字符等数据和算法的链接列表应该很好而且不是很复杂

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

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

请建议一个有效的算法/代码

6 个答案:

答案 0 :(得分:6)

如果你想自己这样做,你基本上想要创建一个数组或链接的元素列表,它们既编码数据又编码数据类型。您可以使用包含类型指示符和要处理的各种类型的并集的结构,以及创建该结构的数组或链接列表:

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指针。

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

答案 1 :(得分:5)

使用boost::variantboost::any。取决于您的需求。

答案 2 :(得分:4)

注意:这是一个纯粹的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;
    .
    .
    .
};

这就是我要做的事。

答案 3 :(得分:2)

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

(当然在解释提升变体给你的内容之前还提到了C / C ++联盟)

答案 4 :(得分:1)

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

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

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

答案 5 :(得分:0)

可以使用 - 正如你所提到的那样 - 使用一些或多或少棘手的宏来处理这些事情。

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

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

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