/* 图的邻接表表示法,以及DFS遍历 */
//思考:如果不是连通图,此代码还适用吗
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>//bool
#define MAX 99 //最大顶点数
bool visited[4] = {false};
typedef int Vertex; //用顶点下标表示顶点
typedef int WeightType;//边的权值为int
typedef char DataType;//顶点存储的数据类型设为字符型
//边的定义
typedef struct Enode *Ptr_To_Enode;
struct Enode
{
Vertex v1,v2; //有向边<v1,v2>
WeightType w; //权重
};
typedef Ptr_To_Enode Edge;
//邻接点的定义
typedef struct AdjVnode *Ptr_To_AdjVnode;
struct AdjVnode
{
Vertex adjv; //邻接点的下标
WeightType w; //边权重
struct AdjVnode* next;//指向下一个邻接点的指针
};
//顶点表头结点的定义
typedef struct Vnode
{
Ptr_To_AdjVnode firstedge; //边表头指针
DataType data;
}AdjList[MAX]; //AdjList是邻接表类型
//图结点的定义
typedef struct Gnode *Ptr_To_Gnode;
struct Gnode
{
int Nv; //顶点数
int Ne;//边数
AdjList G;//邻接表
};
typedef Ptr_To_Gnode LGraph;//以邻接表的方式存储图类型
//初始化一个有VertexNum个顶点但没有边的图
LGraph Create_Graph(int vertexnum)
{
Vertex v;
LGraph graph;
graph = malloc(sizeof(struct Gnode));
graph->Nv = vertexnum;
graph->Ne = 0;
/* 初始化邻接表头指针 */
for ( v = 0; v < graph->Nv; v++)
graph->G[v].firstedge = NULL;
return graph;
}
//插入边
void insert_edge(LGraph G,Edge E)
{
Ptr_To_AdjVnode newnode;
//将边E<v1,v2>插入图中
newnode = malloc(sizeof(struct AdjVnode));//为v2建立新的邻接点
newnode->adjv = E->v2;
newnode->w = E->w;
newnode->next = G->G[E->v1].firstedge;//头插法
G->G[E->v1].firstedge = newnode;
//如果是无向图的话,还需插入<v2,v1>
/* newnode = malloc(sizeof(struct AdjVnode));//为v1建立新的邻接点
newnode->adjv = E->v1;
newnode->w = E->w;
newnode->next = G->G[E->v2].firstedge;
G->G[E->v2].firstedge = newnode;
由于main函数中的edge数组已经包含了<v2,v1>*/
}
LGraph build_graph(int edge[][3],char data[])
{
LGraph Graph; //图
Edge E; //边
Vertex V;//顶点下标
int nv = 4,ne = 10;//顶点数量,边的数量
Graph = Create_Graph(nv);//初始化有nv个顶点无边的图
Graph->Ne = ne;
if (Graph->Ne != 0)
{
E = malloc(sizeof(struct Enode));
for (int i = 0; i < Graph->Ne; i++)
{
E->v1 = edge[i][0];
E->v2 = edge[i][1];
E->w = edge[i][2];
insert_edge(Graph,E);//将边插入图中
}
}
for(int h = 0;h < Graph->Nv;h++)
Graph->G[h].data = data[h];
return Graph;
}
//DFS
void Visit(Vertex V)
{
printf("正在访问顶点%d\n",V);
}
void DFS(LGraph Graph,Vertex V,void (*Visit)(Vertex))
{
/* 以V为出发点对邻接表存储的图Graph进行DFS搜索 */
Ptr_To_AdjVnode W;
Visit(V);
visited[V] = true;
// printf("data:%s\t",Graph->G[V].data);
for ( W = Graph->G[V].firstedge; W ; W = W->next)//递归遍历无向图
{
if(!visited[W->adjv])
DFS(Graph,W->adjv,Visit);
}
printf("data:%c\tV:%d\tj:%d\tw:%d\t\n",Graph->G[V].data,V,Graph->G[V].firstedge->adjv,Graph->G[V].firstedge->w);
}//使用%s的话会调用字符串,那样会越界
int main(void)
{
//分别为v1,v2,w
int edge[][3] = {{0,1,13},{0,2,11},{0,3,17},{1,0,13},{1,2,10},
{2,0,11},{2,1,10},{2,3,7},{3,2,7},{3,0,17}};
char data[4] = {'a','b','c','d'};
LGraph G;
G = build_graph(edge,data);
DFS(G,0,Visit);
return 0;
}
数据结构——图的深度优先搜索使用邻接表
最新推荐文章于 2023-03-23 18:20:41 发布