在c中扩展图形结构

时间:2014-01-18 13:39:10

标签: c algorithm data-structures struct

我的问题:我有一个由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->nn_new2->n以查看它们之间是否存在连接,即是否n_new1->n->n1 == n_new2->n,或n_new1->n->n2 == n_new2->n或反之亦然。如果是这样,我会n_new1->n1 = n_new2n_new1->n2 = n_new2,反之亦然。

但时间复杂度为O(#node^2)。效率低下。

还有其他想法吗?

P.S。该图是一个降阶的二元决策图。

1 个答案:

答案 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

 }

如果没有树,复杂性将是线性的,因此它仍然非常快。 (例如,它与哈希表更加线性。)

(树会将节点*映射到它们的副本。)