繁体   English   中英

C中使用邻接表的无向图(基于Cormen算法)的DFS实现错误

[英]Error in DFS implementation of an undirected graph (based on Cormen algorithm) using adjacency list in C

我在 C 中为使用邻接表表示的图的 DFS 遍历编写了这段代码。它基于 Cormen 中给出的算法。 此代码的问题是“dfs_visit”function 中的 while 循环根本没有执行。 我不明白为什么。 请告诉我原因。 通过 dfs 和 dfs_visit 函数访问 go 可能就足够了,但以防万一您需要通过其他函数访问 go,我将它们全部包括在内。

//颜色:'-1'代表白色; '0' 为灰色; '1' 表示黑色 //白色:未访问; 灰色:已发现但尚未添加; 黑色:访问过

    #include<stdio.h>
    #include<stdlib.h>

    int time;

    struct AdjListNode
    {
        int dest;
        int color;
        int par;//parent
        int dt;//discovered time
        int ft;//finished time
        struct AdjListNode *next;
    };

    struct AdjList
    {
        struct AdjListNode *head;
    };

    struct Graph
    {
        int V;
        struct AdjList *array;
    };
    
    struct AdjListNode *addNewNode(int dest);
    void DFS_visit(struct Graph* graph,struct AdjListNode *u);
    struct Graph *createGraph(int V);
    void addEdge(struct Graph *graph, int src, int dest);
    void printGraph(struct Graph *graph);
    void printDFS(struct Graph* graph);

    struct AdjListNode *addNewNode(int dest)
    {
        struct AdjListNode *newNode = (struct AdjListNode *)malloc(sizeof(struct AdjListNode));
        newNode->dest = dest;
        newNode->dt = newNode->ft = 0;
        newNode->par = 0;
        newNode->next = NULL;
        return newNode;
    }
    
    struct Graph *createGraph(int V)
    {
        struct Graph *graph = (struct Graph *)malloc(V * (sizeof(struct Graph)));
        graph->array = (struct AdjList*)malloc(V*sizeof(struct AdjList));
        graph->V = V;
        for (int i = 0; i < V; i++)
        {
            graph->array[i].head = addNewNode(i);
        }
        return graph;
    }

    void addEdge(struct Graph *graph, int src, int dest)
    {
        struct AdjListNode *newNode = addNewNode(dest);
        // simply adding the node at the beginning
        newNode->next = graph->array[src].head->next;
        graph->array[src].head->next = newNode;
        // for undirected graph
        newNode = addNewNode(src);
        newNode->next = graph->array[dest].head->next;
        graph->array[dest].head->next = newNode;
    }


    void DFS(struct Graph* graph){
        for(int i=0;i<graph->V;i++){
            graph->array[i].head->color = -1;
            graph->array[i].head->par = 0;
        }
        time = 0;
        for(int i=0;i<graph->V;i++){
            if(graph->array[i].head->color == -1){
                DFS_visit(graph,graph->array[i].head);
            }
        }
    }

    void DFS_visit(struct Graph* graph,struct AdjListNode *u){
        u->color = 0;
        u->dt = ++time;
        printf("%d ",u->dest);
        struct AdjListNode* temp = u->next;
        while(temp!=NULL){
            if(temp->color == -1){
                temp->par = u->dest;
                DFS_visit(graph,graph->array[temp->dest].head);
            }
            temp = temp->next;
        }
        u->color = 1;
        u->ft = ++time;
    }

    void printGraph(struct Graph *graph)
    {
        for (int v = 0; v < graph->V; v++)
        {
            struct AdjListNode *temp = graph->array[v].head;
            printf("\nthe adj list of vertex %d is : head", v);
            while (temp)
            {
                printf("-> %d", temp->dest);
                temp = temp->next;
            }
            printf("\n"); 
        }
    }

    void printDFS(struct Graph* graph){
        printf("\n");
        for(int v=0;v<graph->V;v++){
            printf("\nvertex %d has dt = %d & ft = %d",v,graph->array[v].head->dt,graph->array[v].head->ft);
        }
    }

    int main()
    {
        int V;
        printf("enter # of vertices: ");
        scanf("%d",&V);
        struct Graph *graph = createGraph(V);
    
        addEdge(graph,0,1);
        addEdge(graph,1,2);
        addEdge(graph,1,3);
        addEdge(graph,2,3);
        addEdge(graph,2,4);
        addEdge(graph,4,0);

        printGraph(graph);
        printf("\nDFS of given graph is: ");
        DFS(graph);
        printDFS(graph);
        return 0;
    }

printGraph 的 OUTPUT 如下所示,是正确的。
顶点0的邻接表:0->4->1->null
顶点 1 的邻接表:1->3->2->0->null
顶点2的邻接表:2->4->3->1->null
顶点3的邻接表:3->2->1->null
顶点 4 的邻接表:4->0->2->null

重要说明:我在每个顶点的邻接列表的开头添加了 data = vertex 的节点,并使其成为列表的头部。

它给出 0 1 2 3 4 作为 output 但这是错误的。 右边的output是0 4 2 3 1。很明显,正如我前面提到的,“dfs_visit”的while循环没有执行。 请让我知道我必须进行哪些更改才能使此代码正常工作。 “图形打印”没有问题。 邻接列表正在正确打印。

它为 dfs 提供的Output是:
顶点 0 有 dt = 1 和 ft = 2
顶点 1 有 dt = 3 和 ft = 4
顶点 2 有 dt = 5 和 ft = 6
顶点 3 有 dt = 7 和 ft = 8
顶点 4 有 dt = 9 和 ft = 10
显然,这是错误的 output ,就好像 dfs_visit 的 while 循环根本没有执行。 但是,我不明白为什么不是。

欢迎您提出任何优化代码的建议

您的 addEdge 调用 addNewNode 两次,无论边缘是否连接新节点。

在这之后

    addEdge(graph,0,1);
    addEdge(graph,1,2);

该图将有节点 1 的两个副本。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM