【发布时间】:2019-08-07 20:01:03
【问题描述】:
所以我最近遇到了一个大致是这样的数据结构:
template<class T>
struct Node {
size_t m_next;
size_t m_prev;
T m_key;
}
template<class T, size_t N>
struct DS {
Node<T> m_elements[N];
size_t m_head;
size_t m_tail;
}
我简化了一点,只是为了保持简短:当DS 太满时,我不会进行错误处理。通常N 足够大,这不是问题。
一个注释是T必须有某种方式表示“没有价值”;为什么需要这样做可以在下面看到。 (下面我将此值称为TOMBSTONE。)
这种数据结构的 API 与链表的 API 大致相同,但它的性能要好得多,因为一切都很好地适合缓存。
实际实现与链表的不同之处在于它不需要为新节点分配任何新内存。比如推到DS后面大致是这样的:
void DS::push_back(T t) {
size_t attempt = 0;
size_t i = hash(t, attempt++);
while (true) {
if (m_elements[i] == TOMBSTONE) {
m_elements[m_tail].m_next = i;
m_elements[i] = Node(N, m_tail, t);
m_tail = i;
break;
}
i = hash(t, attempt++);
}
}
hash(T t, size_t attempt) 查找尝试插入新元素的位置。 (这样可以很好地传播,而不是一开始就将所有东西都聚集在一起。)
由于与普通链表在性能和实现方面存在巨大差异,我不愿将其称为链表。我还想指出,这个问题与何时 使用什么数据结构,或者上述数据结构是否好/快/安全/其他无关。这种数据结构在我们使用它的特定情况下非常适合我们。
这个特定的实现/数据结构有什么名字吗?
【问题讨论】:
-
链接哈希表?
-
看起来像一个使用预分配节点池的常规链表。
-
指向同一个链表中其他节点的节点是链表。在这种情况下,是一个双链表。这些链接只是使用索引而不是指针,但它们仍然是链接。
-
附注:“一个注释是
T必须有某种方式表示“没有价值”” - 听起来像是std::optional<T>的工作,或者也许std::variant<T, nullptr_t> -
动态分配对于链表来说不是必需的。链接是。
标签: c++ data-structures