我需要一个支持高效的随机访问和O(k)的插入和取出容器高效、容器

2023-09-11 06:02:46 作者:不暖

我又试着问同样的question,但最后我问一个不同的问题通过不提供有关我的问题的基本信息。

I have tried again to ask the same question, but I ended up asking a different question by not providing essential information about my problem.

予实现的数据结构是一棵树。这棵树的每个节点都有一个数组/矢量/(随机存取结构),其所有的孩子可以是任意的多。元素的插入/删除是容易的,因为我们总是双/除以两此数组中元素的个数。

I implement a data structure which is a tree. Each node of this tree has an array/vector/(random access structure) with all its children which can be arbitrary many. The insertion/removal of elements is easy since we always double/divide-by-two the number of the elements in this array.

这是什么 O(K)插入/删除意味着在这方面。我们有 K 元素,我们追加 K 更多或删除 K / 2 。重建整个数据结构细为止。 A 动态数组(或向量)的作品。

That is what the O(k) insertion/removal means in this context. We have k elements and we append k more or delete k/2. Rebuilding the whole data structure is fine so far. A dynamic array (or a vector) works.

这提出了一个问题的操作如下。有时候,我们不得不拆分 N 孩子的节点,这意味着我们鸿沟的不同节点之间的孩子。我们潜水的方式是在连续的群体。最有效的方式对这种分裂是的,我想,有一个指针在那里的孩子们的位置每一个新的节点,有多少(假设每个节点有 K 儿童)。但后来,这些孩子的数量可能会改变,这不应该影响其兄弟姐妹(或更糟的是,整个树),即插入的执行时间应 O(K),而不是 O(N)。我们怎么办呢?

The operation that raises the question is the following. Sometimes we have to "split" a node having n children, which means we "divide" the children among different nodes. The way we dive is in continuous groups. The most efficient way for this split is, I guess, to have one pointer for each new node at the position where its children are and how many there are (let's say each node takes k children). But then, the number of these children may change and that should not affect its siblings (or even worse, the whole tree) i.e the execution time of an insertion should be O(k) and not O(n). How do we do it?

这是容易的,但低效的解决方法是,每次我们分手的一个节点,我们替换了孩子的大数组有许多(多达分裂部分)小动态数组。

An easy but inefficient work-around would be that every time we split a node, we replace the "big" array of children with many (as many as the split parts) "small" dynamic arrays.

每个的下面的拖曳是一个随机存取结构

Each of the following "boxes" is a random access structure.

推荐答案

从你给您所用的树结构的描述,它可能是最好创建一个新的数据结构来模仿你的树。特别是如果你已经在节点之间的跟踪指针。

From the description you gave of the tree structure you are implementing, it might be best to create a new data structure to mimic your tree. Especially if you're already tracking pointers between nodes.

如果我理解你的说法,你的每一个节点,将包含子节点指针的载体。当需要分裂节点,可以用每一个接收儿童指针的载体的片段创建新节点,以及将新创建的节点将被插入到父节点的节点矢量

If I understand your statement, each node in your tree would contain a vector of children node pointers. When you need to split the node, you could create new nodes with each one receiving a segment of the vector of children pointers, and the newly created nodes would be inserted into the node vector of the parent node.

例如:

N 1> N 2>(N3,N4,N5,N6,N7,N8)分裂N2为两个节点: N1 - >(N2_1,N2_2) N2_1->(N3,N4,N5) N2_2-&GT (N6,N7,N8)

N1->N2->(n3,n4,n5,n6,n7,n8) split N2 into two nodes: N1->(N2_1, N2_2) with N2_1->(n3,n4,n5) and N2_2->(n6,n7,n8)

(对不起,我不知道如何轻松地绘制树木...)

(Sorry, I don't know how to easily draw trees...)

这样,你只能重新链接的内存,而不是复制,并获得一般将日志N。此外,这给树结构的code进行适当的重新presentation。

This way, you are only relinking memory rather than copying, and access will generally be log n. Furthermore, this gives a proper representation of the tree structure in code.

修改补充例如:

再次假设,我们有 N 1> N 2>(N3,N4,N5,N6,N7,N8)。如果N1应该需要有新的节点加入时,只影响在N1节点上: N1->(N 2,N9) - >(N3,N4,N5,N6,N7,N8)

Suppose again, we have N1->N2->(n3,n4,n5,n6,n7,n8). If N1 should need to have new nodes added, the only affect is on the N1 node: N1->(N2,N9)->(n3,n4,n5,n6,n7,n8)

节点的结构可能是这样的(很简单):

The structure of a node might be like this (very simplified):

class Node {
  vector<Node *> children;
  Node * parent;
};

较大的树结构。将许多这些节点都连接在一起很像一个二叉树。要将节点添加到任何一个节点上的一棵树只会对子项添加项节点成员。闲来无事受到影响。

The larger tree structure would be many of these nodes all linked together much like a binary tree. To add nodes to any one node on a tree would only add items to the children member of that node. Nothing else is affected.

 
精彩推荐
图片推荐