簡體   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