我的问题:我有一个由node
struct
struct node {
node *n1;
node *n2;
}
我想添加一些成员来创建一个新结构newNode
struct newNode {
newNode *n1;
newNode *n2;
newNode *n3; // new member
int a; // new member
}
我想在图表中保留原始的“节点连接”,以便我可以
newNode *n;
n->n1->n2...
就像
一样node *n;
n->n1->n2...
其中两个结构的n1(或n2)代表图中的同一节点,而我也可以这样做
newNode *n;
n->n1->a...
n->n1->n3...
修改node
结构是很棘手的,因为它在大型库中定义。
我的想法是向newNode
struct
struct newNode {
node *n; // added member
newNode *n1;
newNode *n2;
newNode *n3;
int a;
}
首先,我为每个newNode
n_new
创建node
n
。然后我遍历每对n_new
,比如n_new1和n_new2,查看n_new1->n
和n_new2->n
以查看它们之间是否存在连接,即是否n_new1->n->n1 == n_new2->n
,或n_new1->n->n2 == n_new2->n
或反之亦然。如果是这样,我会n_new1->n1 = n_new2
或n_new1->n2 = n_new2
,反之亦然。
但时间复杂度为O(#node^2)
。效率低下。
还有其他想法吗?
P.S。该图是一个降阶的二元决策图。
答案 0 :(得分:1)
每次遇到新节点时都必须递归复制,创建一个新的new_node(仔细阅读)。这将是原始图表的完整副本,结构相同但使用不同的内存。
为了确定我们是否已经复制了一个节点,我们在一个将节点*映射到new_node *的BST中保留了我们复制的节目列表(及其副本)。
你可以在那里找到许多BST实现。例如,在stl c ++库中有一个,我认为是glibc,依此类推。
代码如下所示:
struct node {
node *n1;
node *n2;
}
struct new_node {
node *n1;
node *n2;
newNode *n3; // new member
int a; // new member
}
new_node* GraphCopy (node* start)
{
new_node* n_new;
if(!start) return NULL;
n_new = malloc(sizeof(new_node));
//Add start.n1 and start.n2 to a bst here
//with keys of node* and vals of new_node*
TreeInsert(start, n_new)
if(IsInTree(start->n1))
n_new->n1 = TreeFind(start->n1);
else
n_new->n1 = GraphCopy(start->n1);
//repeat for n2
}
如果没有树,复杂性将是线性的,因此它仍然非常快。 (例如,它与哈希表更加线性。)
(树会将节点*映射到它们的副本。)