C++ 我需要一个容器,支持有效的随机访问和O(k)插入和删除

C++ 我需要一个容器,支持有效的随机访问和O(k)插入和删除,c++,algorithm,pointers,data-structures,C++,Algorithm,Pointers,Data Structures,我又试着问同样的问题,但最后我问了一个不同的问题,没有提供关于我的问题的基本信息 我实现了一个数据结构,它是一个树。该树的每个节点都有一个数组/向量/(随机访问结构),其所有子节点可以是任意多个。元素的插入/移除很容易,因为我们总是将该数组中的元素数加倍/除以2 这就是O(k)插入/删除在本文中的含义。我们有k元素,我们追加k更多或删除k/2。到目前为止,重建整个数据结构还不错。动态数组(或向量)可以工作 提出问题的操作如下。有时,我们必须将具有子节点的节点“拆分”,这意味着我们将子节点“拆分”

我又试着问同样的问题,但最后我问了一个不同的问题,没有提供关于我的问题的基本信息

我实现了一个数据结构,它是一个树。该树的每个节点都有一个数组/向量/(随机访问结构),其所有子节点可以是任意多个。元素的插入/移除很容易,因为我们总是将该数组中的元素数加倍/除以2

这就是
O(k)
插入/删除在本文中的含义。我们有
k
元素,我们追加
k
更多或删除
k/2
。到目前为止,重建整个数据结构还不错。
动态数组
(或
向量
)可以工作

提出问题的操作如下。有时,我们必须将具有子节点的节点“拆分”,这意味着我们将子节点“拆分”到不同的节点中。我们潜水的方式是连续分组。我想,这种拆分最有效的方法是,在每个新节点的子节点所在的位置和子节点的数量(假设每个节点取
k
子节点)为每个节点设置一个指针。但是,这些子级的数量可能会发生变化,并且不会影响其同级(甚至更糟的是,整个树),即插入的执行时间应该是
O(k)
,而不是
O(n)
。我们怎么做

一个简单但低效的解决方法是,每次分割一个节点时,我们都会将子节点的“大”数组替换为多个(与分割的部分一样多)“小”动态数组

以下每个“框”都是随机访问结构

来一杯怎么样


它得到了摊销的
O(1)
access、insert和remove平均情况
O(n)
最坏情况。

根据您对正在实现的树结构的描述,最好创建一个新的数据结构来模拟您的树。特别是当您已经在跟踪节点之间的指针时

如果我理解您的语句,那么树中的每个节点都将包含子节点指针的向量。当需要拆分节点时,可以创建新节点,每个节点接收子指针向量的一段,新创建的节点将插入父节点的节点向量中

例如:

N1->N2->(n3,n4,n5,n6,n7,n8)
将N2拆分为两个节点:
N1->(N2\u 1,N2\u 2)
with
N2\u 1->(n3,n4,n5)
N2\u 2->(n6,n7,n8)

(对不起,我不知道如何轻松地画树…)

这样,您只需要重新链接内存,而不是复制,访问通常是log n。此外,这在代码中给出了树结构的正确表示

编辑添加示例:

再次假设,我们有
N1->N2->(n3,n4,n5,n6,n7,n8)
。如果N1需要添加新节点,则唯一影响是N1节点:
N1->(N2,N9)->(n3,n4,n5,n6,n7,n8)

节点的结构可能如下所示(非常简化):

类节点{
媒介儿童;
节点*父节点;
};

更大的树结构将是许多这些节点连接在一起,就像二叉树一样。将节点添加到树上的任何一个节点只会将项目添加到该节点的
子节点
成员。其他一切都没有受到影响。

在我看来,你似乎在试图重新创造

B+树的一种变体是存储子元素的数量而不是适当的键,这允许有效的随机访问(
log n
),而您实际上可以控制这些因素

例如,数据库的一个公共因子约为1000,这意味着树的第一级是根,第二级最多可包含1000个子级,第三级最多可包含1000000子级等等

如果对象少于100000000,则意味着最多3次解引用,这是非常有效的


已经有一个Python模块,用这种技术编写,目的是用B+树替换传统的<代码>列表>代码>类(实现为C++ <代码>向量>代码>,以获得更大的效率。可以找到性能测量值。

预计序列会有多大?平均而言,在预测的最坏情况下,您预计一个序列中会有多少个元素?平均而言,在最坏的情况下,您希望每个元素有多大(以字节为单位)?结构中所有节点的子节点的总数可能与此结构存储的元素数相同,该元素数任意大,并表示为
n
(大数组)。另一方面,2是正确的,但在实际应用中,n很少是任意大的;小n的理想数据结构可能与大n的理想数据结构大不相同。优化似乎为时过早。你说std::vector/dynamicarray resize很好,尽管它可能需要执行新的分配并复制每个元素,但是拆分是一个大问题?它执行更多的分配,但复制的级别相同。。。。你有一个你描述过的工作系统吗?我要求的不仅仅是辩论——如果你量化你的问题,你会得到更多、更有用/更相关的帮助。@James我实际上对大量的投入感兴趣@Tony整个项目都是关于这个数据结构的。
split
操作是整个性能的关键。只要复杂性是
O(k)
,那么
向量的大小调整就可以了,也就是说,我们讨论的
向量包含
k
元素,并插入/删除
O(k)
元素。另一方面,如果向量的大小为
n>>k
(由于处理拆分的方式),则成本会爆炸到
O(k)
。请注意摊销O(1
class Node {
  vector<Node *> children;
  Node * parent;
};