【问题标题】:C - Need help implementing an ADTC - 需要帮助实施 ADT
【发布时间】:2016-02-24 03:32:41
【问题描述】:

我正在完成一项学校作业,但我无法理解如何使用 ADT。基本上,我需要实现一个存储<key, value> 对的符号表ADT。与键关联的值是用户定义的任意对象,通过 void 指针传递给 ADT。我已经包含了头文件,我只需要为它制作源文件。

我坚持的声明是针对结构本身的。它是一个符号表对象,由SymTable_T 类型的指针指向。它应该能够复制插入其中的<key, value> 对,并且当从表中删除或表本身被破坏时,这些副本应该被破坏。

实现应该使用一个哈希表,该哈希表使用链接来解决冲突。我已经熟悉散列,所以没有问题。

这是我想出的:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "symTable.h"
#define DEFAULT_TABLE_SIZE 61
#define HASH_MULTIPLIER 65599

typedef struct SymTable *SymTable_T;
{
    char *key;
    int value;
    struct SymTable *next; //linked list
}; 

有人能指出我正确的方向吗?有人可以向我解释实施 ADT 的要点吗?提前非常感谢您!

【问题讨论】:

    标签: c linked-list hashtable abstract-data-type


    【解决方案1】:

    抽象数据类型的本质是客户端代码对该类型值的结构一无所知 - 这也意味着处理此类值的任何函数的实现都是不透明的。

    在您的示例中,这意味着您在头文件中定义struct,而仅使用前向声明。对于遍历,您可能还想定义一个同样不透明的迭代器类型,例如

    struct symtable;
    struct symtable_iterator;
    

    ...然后是处理表格的函数集合,例如

    /* Create symtable, destroy it, insert values. */
    void symtable_alloc(struct symtable **table);
    void symtable_free(struct symtable *table);
    void symtable_insert(struct symtable *table, const char *key, void *value);
    
    /* Create symtable iterator, destroy it, access key/value. */
    void symtable_iterator_alloc(struct symtable *table, struct symtable_iterator **it);
    void symtable_iterator_free(struct symtable_iterator *it);
    bool symtable_iterator_next(struct symtable_iterator **it);
    const char *symtable_iterator_key(struct symtable_iterator *it);
    void *symtable_iterator_value(struct symtable_iterator *it);
    

    这就是你应该放入头文件的所有内容。在实现 (.c) 文件中,您实际上会定义结构及其字段 - 但该代码对客户端是隐藏的。

    你可以像这样使用它们

    struct symtable *table;
    symtable_alloc(&table);
    symtable_insert(table, "one", "eins");
    symtable_insert(table, "two", "zwei");
    symtable_insert(table, "three", "drei");
    
    struct symtable_iterator *it;
    symtable_iterator_alloc(table, &it);
    while (symtable_iterator_next(&it)) {
       printf("%s: %s\n", symtable_iterator_key(it), symtable_iterator_value(it));
    }
    symtable_iterator_free(it);
    symtable_free(table);
    

    请注意,这组函数如何清楚地定义数据结构的 API,但实际类型是抽象的 - 没有任何信息会泄露表的实现,例如无论是链表还是哈希表或其他。

    【讨论】:

    • 感谢您的解释!我已经熟悉头文件/源文件,但你为我澄清了很多。你能评论我的结构或者分解声明typedef struct SymTable *SymTable_T吗?我知道struct SymTable是结构体本身,但是指针指向的是什么?