我想设计一个用于存储元素的数据结构,在插入后只会检索一次,之后会被删除。
我无法使用堆栈或队列,因为无法保证检索顺序。
[编辑] - 我想使用连续的记忆(我宁愿不时地避免做malloc)而且我也更喜欢搜索。
答案 0 :(得分:2)
我认为算法的选择需要更多关于它将如何使用的信息。从你的评论中你想要比线性搜索更好,我假设搜索速度很重要。您对连续内存的评论让我相信您希望最大限度地减少内存消耗。我建议自平衡树结构(Red-Black树)可能是合适的。它会分摊日志(N)插入/删除,允许您实现我概述的两个目标。如果内存使用不是问题,哈希表对于查找会更有效。您可以在连续内存中实现有界大小的树 - 尽管实际元素本身不一定是连续的。
另一方面,如果我知道插入的顺序是随机的,但是检索的顺序是确定性的并且按键排序,那么我可能建议使用堆实现priority queue。
答案 1 :(得分:2)
将仓库需求与数据结构分开。
你说你想要连续的内存 - 我假设你想要抓住一块内存并完全在内存中工作,而不是随着时间的推移分配更多的片段。
现在最简单的情况是在内存块中通过环形缓冲区实现的队列。我认为你想要更好的东西,因为你没有在这里发生过这种情况。
所以某种形式的平衡树听起来就像你需要的那样。选择可能取决于到达键的模式。随机?上升?
皱纹是从你的块中分配内存而不是使用普通的堆分配器,这可能意味着保留一个空闲列表。
知道为什么要重视连续的内存块会很有趣。
答案 2 :(得分:1)
花园品种链表符合您的要求。但是,改进您的要求会产生更好的建议。
例如:
答案 3 :(得分:1)
可能是哈希表或某种树。由于你正在进行大量删除,如果你使用哈希表,它(几乎)需要通过链接来处理冲突。
假设元素大小相同,您可能还需要考虑编写自己的代码来分配元素,以便在元素被删除后轻松地重用元素空间。
编辑:IMO,您可能不想要链接列表。虽然链表使删除本身保持恒定速度,但找到一个元素是线性的,因此总速度为O(N + K)= O(N)。对于哈希表,预期速度为O(1),对于树O(lg N)。
答案 4 :(得分:1)
显然是双重链表。 “你希望你的记忆是连续的”是什么意思?无论你使用哪种数据结构,它都只会是连续的,直到你删除一个元素,之后你必须打包数据以保持连续性。而且严肃地说,当你需要在每次删除后平均移动一半的记录时,无论你使用哪种数据结构都无关紧要,你无论如何都要搞砸了。只需使用动态数组。
答案 5 :(得分:0)
使用red-black tree和memory pool分配来自连续内存块的项目。 Sample implementations of red-black trees written in C are readily available。大多数应该很容易修改,以支持自定义内存分配器,如果他们还没有提供该功能。
答案 6 :(得分:0)
听起来你想要那种无处不在的数据结构 - 数组。在你的情况下是一个动态分配的,类似于C ++ std :: vector类提供的。
答案 7 :(得分:0)
您可以使用(双重)链接列表并保持内存连续。
分配一大块内存来保存所有节点,并跟踪为数据存储分配的节点。
您可以使用多种方法管理预分配的内存。
一种方法是使用可用节点的队列或堆栈,可以取出一个空闲节点,编写数据并将其添加到链表中。完成节点后,将其从链表中删除并将其放回队列/堆栈中。
根据您的堆栈/队列实现,这可能相当于维护两个链接列表。有一点想法应该是一个有效且简约的数据结构和底层代码的设计。