你如何实现一个内存有效的布尔链表?显然,下一个节点指针远大于传统链表中的有效载荷本身。
答案 0 :(得分:4)
将节点对齐超过1字节边界的节点,并使用'next'指针的最低有效位来编码bool值。
我不擅长直接编码到文本框中,但有些内容如下:
struct node {
static_assert(alignof(node) > 1, "node is insufficiently aligned");
bool get_value() const {
return static_cast<bool>(reinterpret_cast<size_t>(next) & 0x1);
}
void set_value(bool value) {
size_t ptr = reinterpret_cast<size_t>(next);
ptr &= ~1;
ptr |= static_cast<size_t>(value);
next = reinterpret_cast<node*>(ptr);
}
node* get_next() const {
size_t ptr = reinterpret_cast<size_t>(next);
ptr &= ~1;
return reinterpret_cast<node*>(ptr);
}
void set_next(node* n) {
bool value = get_value();
next = n;
set_value(value);
}
private:
node* next;
};
答案 1 :(得分:2)
这是一个粗略的想法。在链表节点中,有两个字段,第一个是指向下一个节点的指针,第二个是与系统上的指针大小相等的另一个整数成员。例如,在64位架构上:
struct node {
node *next;
uint64_t bits;
}
然后,每个节点存储64个布尔值,而不仅仅是标准链表实现中的布尔值。许多操作变得不那么节省时间(但这是内存/空间效率的通常权衡),因为当你添加第65个布尔值或插入“完整”位集时,你将不得不进行一些位移和类似于树平衡的东西,等等(另外,考虑到这一点,你可能需要第3个成员告诉你使用的位数。)
然而,这有一些优点,因为像这样的简单结构非常适合缓存。
就像我说的,这只是一个粗略的想法,实现这样的事情可能有很多陷阱。写出好的测试。