当图为稀疏图时,使用邻接矩阵就会浪费很大的存储空间。
这时,图的邻接表法就派上用场了,大大减少了不必要的浪费,
并且可以更方便地增删边。
下面附上图的邻接表实现代码,以及在此基础上的DFS.
/*图的邻接表+深度优先遍历(DFS)(顶点表中顶点序号从0开始)*/
/*注意顶点序号从0开始,如果不注意可能出现越界的错误*/
#include<stdio.h>
#include<stdlib.h>
#define MaxVertexNum 100
typedef int VertexType;
typedef struct ArcNode{ //边表结点
int adjvex; //该弧所指向的顶点的位置序号
struct ArcNode *next; //指向下一条弧的指针
int weight; //边上的权值
}ArcNode;
typedef struct VNode{ //顶点表结点
VertexType data; //顶点信息
ArcNode *first; //指向第一条依附该顶点的弧的指针
}VNode,AdjList[MaxVertexNum];
typedef struct{
AdjList vertices; //邻接表
int vexnum, arcnum; //图的顶点数和弧数
}ALGraph; //ALGraph是以邻接表存储的图类型
int visited[MaxVertexNum];
void CreateALGraph(ALGraph *G); //创建图
void OutputALGraph(ALGraph G); //打印邻接表
void Visit(ALGraph G,int v); //访问顶点
int FirstNeighbor(ALGraph G,int v); //v的第一个邻接点对应的位置序号
int NextNeighbor(ALGraph G, int v,int w); //除v以外的邻接点的位置序号
void DFS(ALGraph G, int v);
void DFSTraverse(ALGraph G);
void main(){
ALGraph G;
CreateALGraph(&G);
OutputALGraph(G);
DFSTraverse(G);
}
void DFSTraverse(ALGraph G){
int v;
for (v = 0; v < G.vexnum; v++)
visited[v] = 0;
printf("\n深度优先遍历序列:\n");
for (v = 0; v < G.vexnum;v++)
if (!visited[v])
DFS(G, v);
}
void DFS(ALGraph G, int v){
Visit(G,v);
visited[v] = 1;
for (int w = FirstNeighbor(G, v); w >= 0; w = NextNeighbor(G, v, w)){
if (!visited[w]){
DFS(G, w);
}
}
}
void Visit(ALGraph G, int v){
printf("%d ", G.vertices[v].data);
}
int FirstNeighbor(ALGraph G, int v){
if (G.vertices[v].first == NULL)
return -1;
return G.vertices[v].first->adjvex;
}
int NextNeighbor(ALGraph G, int v, int w){
ArcNode *p = G.vertices[v].first;
while (p && p->adjvex!=w){
p = p->next;
}
if (!p || !(p->next))
return -1;
return p->next->adjvex;
}
void CreateALGraph(ALGraph *G){
int i;
VertexType vs, ve,weight;
ArcNode *arcNode=NULL;
printf("请输入顶点数和边数:");
scanf("%d %d", &G->vexnum, &G->arcnum);
for (i = 0; i < G->vexnum; i++){
printf("请输入第%d个顶点:", i + 1);
scanf("%d", &G->vertices[i].data);
G->vertices[i].first = NULL;
}
printf("请输入构成每个边的两个顶点和权值(用逗号隔开):\n");
for (i = 0; i < G->arcnum; i++){ //输入各边的两个顶点
printf("第%d条边:", i);
scanf("%d,%d,%d", &vs, &ve, &weight);
arcNode = (ArcNode*)malloc(sizeof(ArcNode));
arcNode->adjvex = ve;
arcNode->weight = weight;
arcNode->next = G->vertices[vs].first;
G->vertices[vs].first = arcNode;
//由于是无向图,彼此相对称
arcNode = (ArcNode*)malloc(sizeof(ArcNode));
arcNode->adjvex = vs;
arcNode->weight = weight;
arcNode->next = G->vertices[ve].first;
G->vertices[ve].first = arcNode;
}
}
void OutputALGraph(ALGraph G){
int i;
for (i = 0; i < G.vexnum; i++){
ArcNode *arcNode = G.vertices[i].first;
printf("%d\t", G.vertices[i].data);
while (arcNode){
printf("%d %d\t", arcNode->adjvex, arcNode->weight);
arcNode = arcNode->next;
}
printf("\n");
}
}