如何实现一套?

时间:2010-03-29 12:08:44

标签: c data-structures

我想在C中实现一个Set。 在创建SET时使用链表是否可以,或者我应该使用其他方法吗?

您通常如何实现自己的设置(如果需要)。

注意: 如果我使用链接列表方法,我可能会有以下复杂性来设置我的操作:

  • init:O(1);
  • 破坏:O(n);
  • insert:O(n);
  • 删除:O(n);
  • union:O(n * m);
  • 交叉口:O(n * m);
  • 差异:O(n * m);
  • ismember:O(n);
  • issubset:O(n * m);
  • setisequal:O(n * m);

O(n * m)似乎可能有点大,特别是对于庞大的数据......有没有办法实现我的Set更高效?

5 个答案:

答案 0 :(得分:8)

通常将集合实现为红黑树(要求元素具有总顺序),或者作为自动调整大小的哈希表(需要哈希函数)。

后者通常通过使哈希表的大小加倍来实现,并在超过某个容量阈值(75%效果良好)时重新插入所有元素。这意味着单独的插入操作可以是O(n),但是当在许多操作中分摊时,它实际上是O(1)。

答案 1 :(得分:5)

std::set通常用红黑树实现:http://en.wikipedia.org/wiki/Red-black_tree

这种方法可以让您在所有列出的操作中获得更好的复杂性。

答案 2 :(得分:4)

我过去曾使用红黑树来建立集合。

以下是维基百科文章的时间复杂性。

空间O(n)
搜索O(log n)
插入O(log n)
删除O(log n)

答案 3 :(得分:3)

设置实现有很多方法。 Here是其中的一部分。除了MSDN之外,还有非常好的文章。

答案 4 :(得分:2)

由于您已经实施了链接列表,因此最简单的是skip list。如果你想使用平衡树,我认为最简单的是treap。这些是随机数据结构,但通常它们与确定性对应物一样有效,如果不是更多(并且可以使跳过列表具有确定性)。