邻接表是图的一种链式存储结构。对图的每个顶点建立一个单链表(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;
}