我必须设计和实现数据结构,其类似于bimap
,bidimap
或dualmap
,即散列表,其中值可以用于提取键,当然也可以用于反方向。具有特定要求的纯C通用双向哈希表
通常情况下,它可以在两个独立的散列表的顶部来实现,但也有一些具体的要求:运行期间
- 的内存分配(更好地分配所有的内存在启动时只)
- 份额在启动时 相同的数据(如果实现为两个哈希表)
- 上限已知
- 键和值可以是任何数据结构(通用)的项的数目,但长度是固定的
- 只有C,没有STL,从头
- 支持删除操作
我至今是:
typedef struct HashTable {
int key_len;
int data_len;
int num_buckets;
HashEntry *buckets;
} HashTable;
typedef struct HashEntry {
void* key;
void* data;
HashEntry* next; //list for collision resolution
} HashEntry;
HashTable* createHashTable (int max_capacity, int num_buckets, int key_len, int data_len);
所以该计划是创建两个哈希表,每个桶的数组。
在长度max_capacity/num_buckets
然后分配字节数组来共享数据,并作为存储器池的条目,每个条目桶预分配列表:
char* p = malloc((key_len+data_len) * max_capacity)
;
然后放函数会把键和数据放到字节数组中,两个哈希表都会相应地分配key
和data
指针。来自
- 碰撞
的主要挑战(超过水桶预期数量,这将需要额外拨款)的内存池的
- 删除操作和管理
如何你会改进设计来应对这些挑战吗?
你能确保*键*和键值都是唯一的(并且映射是双射),或者几个键指向相同的值,或者一个键指向多个值(但是*键,值}仍然是唯一的)?在这两种情况下:当检测到重复时,你想要发生什么? – wildplasser
@wildplasser,键和值是唯一的。 –
顺便说一句:你需要'buckets'数组的两个版本,以及'HashRntries'中的两个' - > next'指针;键和值都需要它们自己的表头和表链。 2)如果键和数据的大小是固定的,你可以将它们存储在一个大数组中(如问题中的'* p'数组),甚至可以存放在HashEntries中。这里不需要指针。 3)下一个指针相同;既然你知道大小是固定的,你可以使用索引而不是指针。索引将受到表大小的限制,可能是16甚至8位宽。 – wildplasser