数据结构 图的邻接表 深度优先遍历(DFS)(C语言版)

当图为稀疏图时,使用邻接矩阵就会浪费很大的存储空间。

这时,图的邻接表法就派上用场了,大大减少了不必要的浪费,

并且可以更方便地增删边。

下面附上图的邻接表实现代码,以及在此基础上的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");
	}

}

 

  • 0
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值