简体   繁体   中英

Starting with graphs

I know this may sound a lot naive, but can someone please explain me how can i implement graphs in C language. I have read the theory, but I am not able to get off the blocks with graph programming.


I would really appreciate if someone could explain how would to create a graph using adjacency lists and adjacency matrix and how would you perform breadth first search and depth first search in C code with some explanations


And before anything, I would like to tell you that this is not a homework. I really want to learn graphs but can't afford a tutor.

I assume that here graph is a collection of vertex and edges. For that you would need an array of pointer to structures. This is adjacency list representation of graph. These structures would having at least an value, which is node number and pointer to another structure. While inserting a new node to graph just go to appropriate index of array and push the node at beginning. This is O(1) time for insertion. My implementation might help you in understanding how it really works. If you are having good skills at C this wouldn't take much longer to understand the code.

//  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;
} 

Well, a real naive and basic answer would be that graph can be represented in C using data structures that contain their pointers to other such data structures. Graphs are really just doubly linked lists that can have multiple links from a single node. If you haven't digested linked lists and doubly linked lists, that'd be a good place to start.

So let's say you have a adjacency list, {a,b},{b,c},{d},{b,e}. First off, you parse that and make a list of all your unique items. (A regular linked list, array, whatever, it's just a temporary structure to help you. You could bypass that, do it on the fly, and probably reap a speedup, but this is simple.) Walking through that list, you generate a node for each item. For each node, you go through the adjacency list again and create an edge when it sees itself. This is a pointer inside the node pointing to another node.

In the end you have a regular list of all you nodes, so you don't lose that lone 'd' node hanging out by itself. You also have a graph of all your nodes so you know their relationship to each other.

Search
Searching across graphs is a pretty basic idea. Start in a node, compare, move to one of it's neighbors and do it again. There are a lot of pitfalls though. Like getting into an endless loop and knowing when to stop.

You'll have to ask more specific questions if you want a better explanation than what you can find online already.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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