邻接表实现图的储存,遍历

邻接表是图的一种链式存储结构。对图的每个顶点建立一个单链表(n个顶点建立n个单链表),第i个单链表中的结点包含顶点Vi的所有邻接顶点。又称链接表。

1.在有向图的邻接表中不易找到指向该顶点的弧。

2.在有向图的邻接表中,对每个顶点,链接的是以该顶点为弧尾的邻接点。

#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <string.h>
#define MAX 100
#define OK 1
#define ERROR 0
 
typedef struct node//表结点 一个顶点对应一个单链表(链表的节点为该顶点的邻接点)vex表示与顶点邻接的点在图中的位置 
{
    int vex;
    struct node *next;
}Node;
 
typedef struct head//头顶点  每个顶点对应一个头结点 first指向第一条边
{
    int data;
    Node *first;
}VNode;
 
typedef struct   //边数 顶点数  存储顶点的数组
{
    VNode list[MAX];
    int v, e;
}Graph;
 
 
void CreatReverseGraph(Graph *G)//有向图逆邻接表
{
    int s, e, i;
    Node *temp;
 
    scanf("%d%d", &(*G).v, &(*G).e);
 
    for (i = 0; i < (*G).v; i++)
    {
        (*G).list[i].first = (Node *)malloc(sizeof(Node));
        ((*G).list[i].first)->next = NULL;
        (*G).list[i].data = 0;
    }
     
    for (i = 0; i < (*G).e; i++)
    {
        scanf("%d%d", &s, &e);
        temp = (Node *)malloc(sizeof(Node));
        temp->vex = s;
        temp->next = ((*G).list[e].first)->next;
        ((*G).list[e].first)->next = temp;
        (*G).list[e].data += 1;
    }
 
}
 
void CreatGraph(Graph *G)//无向图的逆邻接表
{
    int i;
    int s, e;
    Node *temp;
 
    scanf("%d%d", &(*G).v, &(*G).e);
     
    for (i = 0; i < (*G).v; i++)
    {
        (*G).list[i].first = (Node *)malloc(sizeof(Node));
        ((*G).list[i].first)->next = NULL;
        (*G).list[i].data = 0;
    }
    for (i = 0; i < (*G).e; i++)
    {
        scanf("%d%d", &s, &e);
        temp = (Node *)malloc(sizeof(Node));
        temp->vex = e;
        temp->next = ((*G).list[s].first)->next;
        ((*G).list[s].first)->next = temp;
        (*G).list[s].data += 1; 
         
        temp = (Node *)malloc(sizeof(Node));
        temp->vex = s;
        temp->next = ((*G).list[e].first)->next;
        ((*G).list[e].first)->next = temp;
        (*G).list[e].data += 1;
    }
}
 
int FirstVertix(Graph G, int v)//返回顶点v的第一个邻接顶点
{
    Node *temp;
    temp = (G.list[v].first)->next;
     
    if (!temp)
        return -1;
    return temp->vex;
}
 
int NextVertix(Graph G, int v, int w)//返回顶点v相对于w的下一个邻接顶点
{
    Node *temp;
    temp = (G.list[v].first);
     
    for (temp = temp->next; temp; temp = temp->next)
        if (temp->vex == w)
            break;
    if (temp->next == NULL || !temp)
        return -1;
    return temp->next->vex;
 
}
 
void DFS(Graph G, int i, int *visit)//深度优先搜索
{
    int k;
     
    visit[i] = 1;
     
    printf("%d ", i + 1);
    for (k = FirstVertix(G, i); k >= 0; k = NextVertix(G, i, k))//遍历所有邻接顶点,若该顶点未访问,递归深度搜索
        if (!visit[k])
        {
            printf("(%d  %d)\n", i + 1, k + 1);
            DFS(G, k, visit);
        }
}
 
 
void DFSVisit(Graph G)
{
    int visit[MAX];
    int i;
 
    memset(visit, 0, sizeof(int) * G.v);//初始话标记数组visit
     
    for (i = 0; i < G.v; i++)
    {
        if (!visit[i])
            DFS(G, i, visit);
    }
}
 
void BFSVisit(Graph G)//广度优先搜索
{
    int visit[MAX];
    int queue[MAX];//队列存储顶点
    int front = 0, rear = 0;
    int i, j, k;
 
    memset(visit, 0, sizeof(int) * G.v);
     
    for (i = 0; i < G.v; i++)
    {
        if (!visit[i])//访问顶点并将该顶点入队
        {
            visit[i] = 1;
            printf("%d\n", i + 1);
            queue[rear++] = i;
        }
        while (rear != front)
        {
            k = queue[front++];//出队
            for (j = FirstVertix(G, k); j >= 0; j = NextVertix(G, k, j))//遍历该顶点所有邻接顶点
                if (!visit[j])
                {
                    visit[j] = 1;
                    printf("%d ", j + 1);
                    printf("(%d  %d)\n", k + 1, j + 1);
                    queue[rear++] = j;
                }
        }
    }
}
     
 
int main()
{
    Graph G;
 
    CreatGraph(&G);
    //CreatReverseGraph(&G);
    printf("The DFS is:\n");
    DFSVisit(G);
    printf("\nThe BFS is:\n");
    BFSVisit(G);
    return 0;
}

    原文作者:数据结构之图
    原文地址: https://blog.csdn.net/txl199106/article/details/39008911
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞