难以理解使用链接列表实现图形

时间:2017-01-06 15:51:03

标签: c pointers struct graph singly-linked-list

我正在阅读一本关于Algorithms的书,其中包含以下代码。我在这里理解一些问题很困难。

我在以下代码中将my doubt lines显示为DOUBT LINE 1DOUBT LINE 2。 我还评论了REFERENCE一行,我having difficulty要理解。 请详细说明DOUBT LINE 1DOUBT LINE 2

#define MAXV        100     /* maximum number of vertices */
#define NULL        0       /* null pointer */

/*  DFS edge types      */

#define TREE        0       /* tree edge */
#define BACK        1       /* back edge */
#define CROSS       2       /* cross edge */
#define FORWARD     3       /* forward edge */

typedef struct edgenode {
    int y;              /* adjancency info */
    int weight;         /* edge weight, if any */
    struct edgenode *next;      /* next edge in list */
} edgenode;

typedef struct {
    edgenode *edges[MAXV+1];    /* adjacency info */       //REFERENCE 
    int degree[MAXV+1];     /* outdegree of each vertex */
    int nvertices;          /* number of vertices in the graph */
    int nedges;         /* number of edges in the graph */
    int directed;           /* is the graph directed? */
} graph;

它是graph.h标题,它也是读取和插入函数。

read_graph(graph *g, bool directed)
{
    int i;              /* counter */
    int m;              /* number of edges */
    int x, y;           /* vertices in edge (x,y) */

    initialize_graph(g, directed);

    scanf("%d %d",&(g->nvertices),&m);

    for (i=1; i<=m; i++) {
        scanf("%d %d",&x,&y);
        insert_edge(g,x,y,directed);
    }
}

insert_edge(graph *g, int x, int y, bool directed)
{
    edgenode *p;            /* temporary pointer */

    p = malloc(sizeof(edgenode));   /* allocate storage for edgenode */

    p->weight = NULL;
    p->y = y;
    p->next = g->edges[x]; //DOUBT LINE1

    g->edges[x] = p;        /* insert at head of list */ //DOUBT LINE 2

    g->degree[x] ++;        

    if (directed == FALSE)
        insert_edge(g,y,x,TRUE);
    else
        g->nedges ++;
}

3 个答案:

答案 0 :(得分:0)

每个顶点都有一组边。我们可以认为该集合是无序的。在mutator函数之外的所有时间,指针g->edges[i]指向edgenode顶点上的第一个i事件,否则指向NULL。然后,next中的edgenode链接指向集合中的其他边缘,可传递。

因此,要添加边,首先要创建一个新边,然后将其next指针指定为当前“第一个”节点(DOUBT LINE 1),然后为新创建的g->edges[i]指针指定价值(DOUBT LINE 2)。

请注意,我说上面需要存在的条件仍然满足,尽管节点的顺序已经改变 - “先前”的第一个现在是第二个,而新节点是第一个。没关系,因为我们只是存储一套 - 订单无关紧要。

之前(=&gt;遍历'下一个'链接):

   // edges[i] == <previous> => <other stuff>...

后:

   //         *             *    These asterisks are above what we set...
   //edges[i] == <new node> => <previous> => <other stuff>

答案 1 :(得分:0)

链接列表表示next是指向以下节点的指针。 例如:
a {some_data,pointer_to_b}
b {some_data,pointer_to_c}
如果要插入节点,必须将前一节点的next指针更改为新节点,并将新节点的next指针设置为后续节点的地址。 例如:
a {some_data,pointer_to_d/*what is done at doubt line 1*/}
d {some_data,pointer_to_b} //插入节点在疑问线2处完成的操作 b {some_data,pointer_to_c}

答案 2 :(得分:0)

让我们剖析,以便你清楚地理解一切。

图表的结构

1o-->2o-->#
2o-->3o-->#
3o-->#
4o-->#
5o--.#

这里

 `1o`: The node 1

 `-->`: It denotes a directed edge.

 `#`: denotes `NULL`

现在让我们添加权重= 5的2-->4边缘

步骤1:p = malloc(sizeof(edgenode));

p-------->[ ]   ( This is the allocated node)

步骤2:p->weight = NULL; //它应该是边缘的权重           p->y = y;

| wieght = 5 |
| y = 4      |
| next       |

第3步:p->next = g->edges[x]; g-&gt; edges [2]是指向3o

的指针
| wieght = w |
| y = 4      |
| next =------------>3o

现在图片是

1o-->2o--->#

p[]--+
     |
     V
2o-->3o--->#
3o-->#
4o-->#
5o--.#

第4步:g->edges[2]=p g->edges[2]基本上是2o

1o-->2o--->#
2o-->[] --> 3o--->#
3o-->#
4o-->#
5o-->#

简单地

1o-->2o--->#
2o-->4o--->3o--->#
3o-->#
4o-->#
5o-->#

说明:

基本上我们在这里维护一个列表,对于每个节点x我们放y,z,如果有边x->yx->z

如果我们查看实现,我们将看到节点被添加到前面。

例如..如果我们添加x->y,则边缘列表将显示为

x---->y

现在添加z。

x---->z---->y

所有这些...一个友好的提示,当你没有得到一个代码得到铅笔和纸张尝试干运行或它或有时只是运行调试器。