圖(鄰接表)


  我們先來看一個圖

我們想將這個圖的信息存儲到鄰接表中,我們需要一個數組保存節點信息,還要有一個節點用來保存與該節點相鄰的節點信息.

 1 typedef struct arc_node
 2 {
 3     int pos;
 4     int distance;
 5     struct arc_node * next;
 6 } Arc_node;//保存Node節點的相鄰節點信息
 7 
 8 typedef struct node
 9 {
10     node_type info;
11     Arc_node * next;
12 } Node;//保存節點信息
13 
14 typedef struct graph
15 {
16     Node vertexs[MAX_NUM];
17     int vertex, arc;
18 } Graph;//鄰接表

如果將上面的圖用鄰接表存儲,我們將回看到這樣一幅圖

每個字符后面的數字代表與它相鄰的節點在數組中的位置(在Arc_node里存有權值,這里沒有顯示)

構造鄰接表:

1)先輸入節點個數及節點信息.

2)在輸入某節點的相鄰節點及權值.(這時,每輸入一個相鄰節點,就構建一個Arc_node節點,將Arc_node接到該節點的最后)

 1 void g_create(Graph * graph)
 2 {
 3     int num;
 4     int i, j, k;
 5     char c;
 6     Arc_node * tmp;
 7 
 8     printf("輸入節點個數:");
 9     scanf("%d", &graph->vertex);
10     getchar();
11     printf("輸入頂點信息:");
12     for ( i = 0; i < graph->vertex; i++ )
13     {
14         scanf("%c", &graph->vertexs[i].info);
15         graph->vertexs[i].next = NULL;
16         getchar();
17     }
18 
19     for ( i = 0; i < graph->vertex; i++ )
20     {
21         printf("輸入與節點%c相鄰的節點和權值,#號鍵結束\n", graph->vertexs[i].info);
22         for ( j = 0; j < graph->vertex; j++ )
23         {
24             scanf("%c", &c);
25             if ( c == '#' )
26             {
27                 getchar();
28                 break;
29             }
30             scanf("%d", &num);
31             getchar();
32             for ( k = 0; k < graph->vertex; k++ )
33             {
34                 if ( graph->vertexs[k].info != c )
35                     continue;
36                 if ( graph->vertexs[k].next == NULL )
37                     graph->vertexs[k].next = make_node(i, num);
38                 else
39                 {
40                     tmp = graph->vertexs[k].next;
41                     while ( tmp->next != NULL )
42                         tmp = tmp->next;
43                     tmp->next = make_node(i, num);
44                 }
45             }
46         }
47     }
48 }

深度優先遍歷

鄰接表的深度優先遍歷根鄰接矩陣的差不多.只是由於數據的存儲方式有點差別,所以代碼實現會有些不同,但思路還是一樣的.

 1 static void dfs_graph(Graph * graph, bool visited[], const int i);
 2 void g_depth_first_search(Graph * graph)
 3 {
 4     bool visited[graph->vertex];
 5     int i;
 6 
 7     for ( i = 0; i < graph->vertex; i++ )
 8         visited[i] = false;
 9 
10     visited[0] = true;
11     dfs_graph(graph, visited, 0); 
12 }
13 
14 static void dfs_graph(Graph * graph, bool visited[], const int i)
15 {
16     Arc_node * tmp;
17     printf("%c\t", graph->vertexs[i].info);
18 
19     tmp = graph->vertexs[i].next;
20     while ( tmp != NULL )
21     {
22         if ( !visited[tmp->pos] )
23         {
24             visited[tmp->pos] = true;
25             dfs_graph(graph, visited, tmp->pos);
26         }
27         tmp = tmp->next;
28     }
29 }

廣度優先遍歷

 1 void g_breadth_first_search(Graph * graph)
 2 {
 3     Queue queue;
 4     bool visited[graph->vertex];
 5     int pos;
 6     int i;
 7     Arc_node * tmp;
 8 
 9     q_init(&queue);
10     for ( i = 0; i < graph->vertex; i++ )
11         visited[i] = false;
12 
13     visited[0] = true;
14     q_push(&queue, 0);
15     while ( !q_empty(&queue) )
16     {
17         pos = q_front(&queue);
18         printf("%c\t", graph->vertexs[pos].info);
19         tmp = graph->vertexs[pos].next;
20         while ( tmp != NULL )
21         {
22             if ( !visited[tmp->pos] )
23             {
24                 visited[tmp->pos] = true;
25                 q_push(&queue, tmp->pos);
26             }
27             tmp = tmp->next;
28         }
29         q_pop(&queue);
30     }
31     printf("\n");
32 }

對於深度優先遍歷和廣度優先遍歷的算法思路不清楚的同學請先看鄰接矩陣.

graph.c

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

#include "aqueue.h"

#define MAX_NUM 100
typedef char node_type;

typedef struct arc_node
{
    int pos;
    int distance;
    struct arc_node * next;
} Arc_node;//保存Node節點的相鄰節點信息

typedef struct node
{
    node_type info;
    Arc_node * next;
} Node;//保存節點信息

typedef struct graph
{
    Node vertexs[MAX_NUM];
    int vertex, arc;
} Graph;//鄰接表

static Arc_node * make_node(const int pos, const int distance)
{
    Arc_node * new_node = (Arc_node *)malloc( sizeof(Arc_node) );
    if ( new_node == NULL )
        exit(1);

    new_node->next = NULL;
    new_node->distance = distance;
    new_node->pos = pos;

    return new_node;
}

void g_create(Graph * graph)
{
    int num;
    int i, j, k;
    char c;
    Arc_node * tmp;

    printf("輸入節點個數:");
    scanf("%d", &graph->vertex);
    getchar();
    printf("輸入頂點信息:");
    for ( i = 0; i < graph->vertex; i++ )
    {
        scanf("%c", &graph->vertexs[i].info);
        graph->vertexs[i].next = NULL;
        getchar();
    }

    for ( i = 0; i < graph->vertex; i++ )
    {
        printf("輸入與節點%c相鄰的節點和權值,#號鍵結束\n", graph->vertexs[i].info);
        for ( j = 0; j < graph->vertex; j++ )
        {
            scanf("%c", &c);
            if ( c == '#' )
            {
                getchar();
                break;
            }
            scanf("%d", &num);
            getchar();
            for ( k = 0; k < graph->vertex; k++ )
            {
                if ( graph->vertexs[k].info != c )
                    continue;
                if ( graph->vertexs[k].next == NULL )
                    graph->vertexs[k].next = make_node(i, num);
                else
                {
                    tmp = graph->vertexs[k].next;
                    while ( tmp->next != NULL )
                        tmp = tmp->next;
                    tmp->next = make_node(i, num);
                }
            }
        }
    }
}

static void dfs_graph(Graph * graph, bool visited[], const int i);
void g_depth_first_search(Graph * graph)
{
    bool visited[graph->vertex];
    int i;

    for ( i = 0; i < graph->vertex; i++ )
        visited[i] = false;

    visited[0] = true;
    dfs_graph(graph, visited, 0); 
}

static void dfs_graph(Graph * graph, bool visited[], const int i)
{
    Arc_node * tmp;
    printf("%c\t", graph->vertexs[i].info);

    tmp = graph->vertexs[i].next;
    while ( tmp != NULL )
    {
        if ( !visited[tmp->pos] )
        {
            visited[tmp->pos] = true;
            dfs_graph(graph, visited, tmp->pos);
        }
        tmp = tmp->next;
    }
}

void g_breadth_first_search(Graph * graph)
{
    Queue queue;
    bool visited[graph->vertex];
    int pos;
    int i;
    Arc_node * tmp;

    q_init(&queue);
    for ( i = 0; i < graph->vertex; i++ )
        visited[i] = false;

    visited[0] = true;
    q_push(&queue, 0);
    while ( !q_empty(&queue) )
    {
        pos = q_front(&queue);
        printf("%c\t", graph->vertexs[pos].info);
        tmp = graph->vertexs[pos].next;
        while ( tmp != NULL )
        {
            if ( !visited[tmp->pos] )
            {
                visited[tmp->pos] = true;
                q_push(&queue, tmp->pos);
            }
            tmp = tmp->next;
        }
        q_pop(&queue);
    }
    printf("\n");
}

int main(void)
{
    Graph graph;
    Arc_node * node;
    int i;
    
    g_create(&graph);

    for ( i = 0; i < graph.vertex; i++ )
    {
        printf("%c\t", graph.vertexs[i].info);
        node = graph.vertexs[i].next;
        while ( node != NULL )
        {
            printf("%d %d\t", node->distance, node->pos);
            node = node->next;
        }
        printf("\n");
    }
    printf("\n");

    g_depth_first_search(&graph);
    printf("\n");
    g_breadth_first_search(&graph);

    return 0;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM