【问题标题】:What data structure should i use to support insert, delete and random selection?我应该使用什么数据结构来支持插入、删除和随机选择?
【发布时间】:2015-09-10 09:25:29
【问题描述】:

我需要创建一个支持以下操作的整数数据结构 -

  1. 在给定位置插入项目(添加项目位置)
  2. 从给定位置删除项目(删除位置)
  3. 随机选择任意给定位置(选择位置)
  4. 随机洗牌。

我需要保持一个头。由 () 表示。有关详细信息,请参阅示例。

Ex- 

lets say my initial state is 
(1) 2 3 4 5
Where () represents my current head

After Add 6 2
state  - (1) 6 2 3 4 5

After Delete 5
state  - (1) 6 2 3 5

After Select 3
state  - 1 6 (2) 3 5

After shuffle 
state  - 5 (2) 6 1 3
 shuffle will shuffle all the items randomly. But will preserve the head.

【问题讨论】:

  • 这取决于很多事情,如果您期望少量元素(如 20 个或更少),则向量可能会更好。但是,对于大量元素,例如从向量中间插入和删除是昂贵的......
  • std::vector 似乎可以解决问题。
  • @Kerrek SB 我绑定了数组,该数组涉及在项目之间插入和删除的情况下的项目移动。然后我也想到了链接列表。但我的大部分操作都涉及随机访问,所以链接列表不是一个好主意。我探索了 Array + Hash 的选项。我正在寻找是否有更好的选择,但我不知道。
  • 根据经验,如果您没有特定理由来选择其他东西,那么向量就可以了。如果您有 6 个对象,则使用向量的程序将在另一个程序甚至分配链表中的第一个节点之前完成。
  • @LPs SO:s 的政策是,为什么有人需要答案并不重要。无论是关于初学者作业还是航天飞机固件,所有问题都必须符合相同的质量标准。因此,“闻起来像家庭作业”的 cmets 没有建设性或相关性。

标签: c++ c algorithm data-structures


【解决方案1】:

创建每个大小为 2k 的 bin,并拥有其中的 n/k 个(因此分配的空间总数为 2n)。

  • 每个“bin”都会知道它的开始索引和结束索引。
  • 插入时,先找到相关的bin。如果使用线性搜索,这需要 O(n/k) 时间。将元素添加到 bin 中(假设暂时未满),然后向右移动该特定 bin 中的所有元素。然后,更新您刚刚修改的 bin 之后的所有 bin。这将花费O(n/k + k) 时间。
  • 删除与添加类似,在O(n/k + k)时间再次完成。
  • 选择:找到相关的箱子(同样,线性搜索会给你O(n/k),并且项目在其中的位置在O(1)中找到)。但是请注意,您可以在 O(log(n/k)) 时间使用二进制搜索找到 bin,因此选择是 O(log(n/k))
  • O(n) 中使用fisher yates 随机播放。

此外,当 bin 已满时,只需重新分配整个数组,如果需要 - 增加 bin 大小。这个操作是O(n),并且至少在O(k) 插入之后完成,所以在讨论摊销时间时,它仍然是每次插入O(n/k)

我们现在要做的就是找到最优的k,所以我们要最小化n/k + k

f(k) = n/k + k, 0 < k <=n
df/dk = n*-1*k^(-2) + 1 = 0
1/n = 1/k^2
n = k^2
sqrt(n) = k

因此,为了最佳选择k,我们需要k=sqrt(n),我们得到了复杂性:

  • 插入:O(sqrt(n))
  • 删除:O(sqrt(n))
  • 选择:O(log(sqrt(n))) = O(log(n))
  • 随机播放:O(n)

【讨论】:

    猜你喜欢
    • 2014-03-04
    • 1970-01-01
    • 1970-01-01
    • 2013-02-22
    • 1970-01-01
    • 2013-11-16
    • 1970-01-01
    • 1970-01-01
    • 2013-04-06
    相关资源
    最近更新 更多