繁体   English   中英

从图表开始

[英]Starting with graphs

我知道这可能听起来很天真,但有人可以解释一下我如何用C语言实现图形。 我已经读过这个理论,但是我无法通过图形编程来解决问题。


如果有人能够解释如何使用邻接列表和邻接矩阵创建图形,我将非常感激,您将如何在C代码中执行广度优先搜索和深度优先搜索以及一些解释


在此之前,我想告诉你,这不是一个功课。 我真的想学习图表但却买不起导师。

我假设这里的图是顶点和边的集合。 为此,您需要一个指向结构的指针数组。 这是图的邻接列表表示。 这些结构至少具有一个值,即节点号和指向另一个结构的指针。 在图形中插入新节点时,只需转到相应的数组索引并在开始时推送节点。 这是O(1)插入时间。 我的实现可能会帮助您了解它是如何工作的。 如果你在C语言上有很好的技能,那么理解代码就不会花费太长时间。

//  Graph implementation by adjacency list

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

#define MAX_SIZE 1000

typedef struct node{
    int number;
    struct node * next;
} Node;


//  U is starting node, V is ending node
void addNode (Node *G[], int U, int V, int is_directed)
{
    Node * newnode = (Node *)malloc(sizeof(Node));
    newnode->number = V;
    newnode->next = G[U];
    G[U] = newnode;

//  0 for directed, 1 for undirected
    if (is_directed)
    {
        Node * newnode = (Node *)malloc(sizeof(Node));
        newnode->number = U;
        newnode->next = G[V];
        G[V] = newnode;
    }
}

void printgraph(Node *G[], int num_nodes)
{
    int I;
    for (I=0; I<=num_nodes; I++)
    {
        Node *dum = G[I];
        printf("%d : ",I);
        while (dum != NULL)
        {
            printf("%d, ",dum->number);
            dum =dum->next;
        }
        printf("\n");
    }

}



void dfs (Node *G[], int num_nodes, int start_node)
{
    int stack[MAX_SIZE];
    int color[num_nodes+1];
    memset (color, 0, sizeof(color));
    int top = -1;
    stack[top+1] = start_node;
    top++;
    while (top != -1)
    {
        int current = stack[top];
        printf("%d  ",current);
        top--;
        Node *tmp = G[current];
        while (tmp != NULL)
        {
            if (color[tmp->number] == 0)
            {
                stack[top+1] = tmp->number;
                top++;
                color[tmp->number] = 1;
            }
            tmp = tmp->next;
        }
    }

}

void bfs (Node *G[], int num_nodes, int start_node)
{
    int queue[MAX_SIZE];
    int color[num_nodes+1];
    memset (color, 0, sizeof (color));
    int front=-1, rear=-1;
    queue[rear+1] = start_node;
    rear++;printf("\n\n");
    while (front != rear)
    {
        front++;
        int current = queue[front];
        printf("%d  ",current);

        Node *tmp = G[current];
        while (tmp != NULL)
        {
            if (color[tmp->number] == 0)
            {
                queue[rear+1] = tmp->number;
                rear++;
                color[tmp->number] = 1;
            }
            tmp = tmp->next;
        }
    }

}  

int main(int argc, char **argv)
{
    int num_nodes;
    // For Demo take num_nodes = 4
    scanf("%d",&num_nodes);
    Node *G[num_nodes+1];
    int I;
    for (I=0; I<num_nodes+1 ;I++ )
        G[I] = NULL;

    addNode (G, 0, 2, 0);
    addNode (G, 0, 1, 0);
    addNode (G, 1, 3, 0);
    addNode (G, 2, 4, 0);
    addNode (G, 2, 1, 0);
    printgraph( G, num_nodes);
    printf("DFS on graph\n");
    dfs(G, num_nodes, 0);
    printf("\n\nBFS on graph\n");
    bfs(G, num_nodes, 0);

    return 0;
} 

好吧,一个真正天真和基本的答案是,图表可以使用包含指向其他此类数据结构的指针的数据结构在C中表示。 图表实际上只是双链表,可以从单个节点拥有多个链接。 如果你还没有消化链表和双链表,那将是一个很好的起点。

因此,假设您有一个邻接列表{a,b},{b,c},{d},{b,e}。 首先,您解析它并列出所有独特的项目。 (一个常规的链表,数组,无论如何,它只是一个临时的结构来帮助你。你可以绕过它,动态地做,并且可能获得加速,但这很简单。)通过该列表,你生成一个每个项目的节点。 对于每个节点,您将再次浏览邻接列表,并在看到自身时创建边缘。 这是指向另一个节点的节点内的指针。

最后,您有一个包含所有节点的常规列表,因此您不会丢失单独的“d”节点。 您还有一个所有节点的图表,以便您了解它们之间的关系。

搜索
搜索图表是一个非常基本的想法。 从节点开始,比较,移动到其中一个邻居并再次执行。 但是有很多陷阱。 就像进入一个无限循环,知道何时停止。

如果你想要一个比你在网上找到的更好的解释,你将不得不提出更具体的问题。

暂无
暂无

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

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