【数据结构-图】C语言实现邻接表表示无向图(网)和有向图(网)及深度遍历

邻接表表示法创建图

创建无向图

创建这样一个无向图。
在这里插入图片描述
用邻接表表示,则是如下:
在这里插入图片描述

存储表示

//存储表示 
int visited[MVNum]; 
typedef int Status;
typedef char VerTexType; 
typedef int OtherInfo;     
typedef struct ArcNode
{
	int adjvex;             //该边指向顶点的位置 
	struct ArcNode *nextarc;  //指向下一条边的指针 
	OtherInfo info;           //和边相关的信息,例如:权值 
}ArcNode;
typedef struct VNode 
{
	VerTexType data;        //存储顶点名字或一些相关信息 
	ArcNode *firstarc;      //指向链表中第一个结点 
}VNode,AdjList[MVNum];    //AdjList 则是数组类型
typedef struct
{
	AdjList vertices;      //vertices VNode类型的一个数组,表示顶点表 
	int vexnum,arcnum;    //顶点数和边数 
}ALGraph;

定位顶点位置

//在顶点表里定位顶点的位置
int LocateVex(ALGraph G,char v)  //顶点名称v 
{
	for(int i=0;i<G.vexnum;i++)
		if(G.vertices[i].data==v) return i;
}

创建无向图

//创建无向图
Status CreateUDG(ALGraph *G)
{
	printf("请输入顶点数和边数:");
	scanf("%d %d",&(*G).vexnum,&(*G).arcnum);    //输入顶点数和边数 
	printf("请输入%d顶点名称:",(*G).vexnum);    
	for(int i=0;i<(*G).vexnum;i++)
	{
		scanf(" %c",&((*G).vertices[i].data));   //输入图的顶点名称 
		(*G).vertices[i].firstarc = NULL;        //顶点表指向边链表指针初始化为NULL 
	}
	for(int k=0;k<(*G).arcnum;k++)
	{
		int i,j;
		char v1,v2;     //两个顶点
		printf("请输入连接那条边的两个顶点:");
		scanf(" %c%c",&v1,&v2);
		i=LocateVex(*G,v1);      //定位两个顶点的位置 
		j=LocateVex(*G,v2);
		ArcNode *p1 = (ArcNode *)malloc(sizeof(ArcNode));   //开辟一个结点加到 边链表里 
		p1->nextarc = (*G).vertices[i].firstarc;    //边链表新加入结点插到头 
		p1->adjvex = j;       //将边的另一个顶点位置设置为j
		p1->info = 1;         //权值 
		(*G).vertices[i].firstarc = p1;   //顶点连接边链表 
		//无向网另一顶点
		ArcNode *p2 = (ArcNode *)malloc(sizeof(ArcNode));
		p2->nextarc = (*G).vertices[j].firstarc;
		p2->adjvex = i;
		p2->info = 1;
		(*G).vertices[j].firstarc = p2;		
	}
	return OK;
}

邻接表无向图深度优先遍历

//邻接表深度优先遍历
void DFS(ALGraph G,int i)
{
	ArcNode *p;     //指向边链表结点指针 
	visited[i]=1;   //辅助数组该位置设置为1 
	printf("%c",G.vertices[i].data);
	p=G.vertices[i].firstarc;    //指向边链表结点首结点 
	while(p)    //指针不为空继续循环 
	{
		if(!visited[p->adjvex]) 
			DFS(G,p->adjvex);
		p=p->nextarc;    //继续指向下一个结点 
	}
}

深度优先遍历基本操作

//深度优先遍历基本操作
void DFSTraverse(ALGraph G)
{
	//初始化辅助数组
	for(int i=0;i<G.vexnum;i++)    //初始化辅助数组 
		visited[i]=0;
	for(int i=0;i<G.vexnum;i++)     //从第一个顶点作为入口进行遍历 
		if(!visited[i]) DFS(G,i);
}

测试代码整合

#include <stdio.h>
#include <stdlib.h>

#define MVNum 100
#define OK 1

//存储表示 
int visited[MVNum]; 
typedef int Status;
typedef char VerTexType; 
typedef int OtherInfo;     
typedef struct ArcNode
{
	int adjvex;             //该边指向顶点的位置 
	struct ArcNode *nextarc;  //指向下一条边的指针 
	OtherInfo info;           //和边相关的信息,例如:权值 
}ArcNode;
typedef struct VNode 
{
	VerTexType data;        //存储顶点名字或一些相关信息 
	ArcNode *firstarc;      //指向链表中第一个结点 
}VNode,AdjList[MVNum];    //AdjList 则是数组类型
typedef struct
{
	AdjList vertices;      //vertices VNode类型的一个数组,表示顶点表 
	int vexnum,arcnum;    //顶点数和边数 
}ALGraph;

//在顶点表里定位顶点的位置
int LocateVex(ALGraph G,char v)  //顶点名称v 
{
	for(int i=0;i<G.vexnum;i++)
		if(G.vertices[i].data==v) return i;
}

//创建无向网 
Status CreateUDG(ALGraph *G)
{
	printf("请输入顶点数和边数:");
	scanf("%d %d",&(*G).vexnum,&(*G).arcnum);    //输入顶点数和边数 
	printf("请输入%d顶点名称:",(*G).vexnum);    
	for(int i=0;i<(*G).vexnum;i++)
	{
		scanf(" %c",&((*G).vertices[i].data));   //输入图的顶点名称 
		(*G).vertices[i].firstarc = NULL;        //顶点表指向边链表指针初始化为NULL 
	}
	for(int k=0;k<(*G).arcnum;k++)
	{
		int i,j;
		char v1,v2;     //两个顶点
		printf("请输入连接那条边的两个顶点:");
		scanf(" %c%c",&v1,&v2);
		i=LocateVex(*G,v1);      //定位两个顶点的位置 
		j=LocateVex(*G,v2);
		ArcNode *p1 = (ArcNode *)malloc(sizeof(ArcNode));   //开辟一个结点加到 边链表里 
		p1->nextarc = (*G).vertices[i].firstarc;    //边链表新加入结点插到头 
		p1->adjvex = j;       //将边的另一个顶点位置设置为j
		p1->info = 1;         //权值 
		(*G).vertices[i].firstarc = p1;   //顶点连接边链表 
		//无向网另一顶点
		ArcNode *p2 = (ArcNode *)malloc(sizeof(ArcNode));
		p2->nextarc = (*G).vertices[j].firstarc;
		p2->adjvex = i;
		p2->info = 1;
		(*G).vertices[j].firstarc = p2;		
	}
	return OK;
}

//邻接表深度优先遍历
void DFS(ALGraph G,int i)
{
	ArcNode *p;     //指向边链表结点指针 
	visited[i]=1;   //辅助数组该位置设置为1 
	printf("%c",G.vertices[i].data);
	p=G.vertices[i].firstarc;    //指向边链表结点首结点 
	while(p)    //指针不为空继续循环 
	{
		if(!visited[p->adjvex]) 
			DFS(G,p->adjvex);
		p=p->nextarc;    //继续指向下一个结点 
	}
}

//深度优先遍历基本操作
void DFSTraverse(ALGraph G)
{
	//初始化辅助数组
	for(int i=0;i<G.vexnum;i++)    //初始化辅助数组 
		visited[i]=0;
	for(int i=0;i<G.vexnum;i++)     //从第一个顶点作为入口进行遍历 
		if(!visited[i]) DFS(G,i);
}

int main()
{
	ALGraph G;
	CreateUDG(&G);
	DFSTraverse(G);
	return 0;
}

深度遍历结果

在这里插入图片描述

创建无向网

创建这样一个无向网。
在这里插入图片描述

代码表示

其实就是修改了第23行和29行输入权值。其余代码于无向图一致。

//创建无向网 
Status CreateUDG(ALGraph *G)
{
	printf("请输入顶点数和边数:");
	scanf("%d %d",&(*G).vexnum,&(*G).arcnum);    //输入顶点数和边数 
	printf("请输入%d顶点名称:",(*G).vexnum);    
	for(int i=0;i<(*G).vexnum;i++)
	{
		scanf(" %c",&((*G).vertices[i].data));   //输入图的顶点名称 
		(*G).vertices[i].firstarc = NULL;        //顶点表指向边链表指针初始化为NULL 
	}
	for(int k=0;k<(*G).arcnum;k++)
	{
		int i,j;
		char v1,v2;     //两个顶点
		printf("请输入连接那条边的两个顶点:");
		scanf(" %c%c",&v1,&v2);
		i=LocateVex(*G,v1);      //定位两个顶点的位置 
		j=LocateVex(*G,v2);
		ArcNode *p1 = (ArcNode *)malloc(sizeof(ArcNode));   //开辟一个结点加到 边链表里 
		p1->nextarc = (*G).vertices[i].firstarc;    //边链表新加入结点插到头 
		p1->adjvex = j;       //将边的另一个顶点位置设置为j
		scanf("%d",&p1->info); 
		(*G).vertices[i].firstarc = p1;   //顶点连接边链表 
		//无向网另一顶点
		ArcNode *p2 = (ArcNode *)malloc(sizeof(ArcNode));
		p2->nextarc = (*G).vertices[j].firstarc;
		p2->adjvex = i;
		p2->info = p1->info;
		(*G).vertices[j].firstarc = p2;		
	}
	return OK;
}

深度遍历结果

在这里插入图片描述

创建有向图

创建这样一个有向图
在这里插入图片描述
邻接表表示:
在这里插入图片描述

代码表示

//创建有向图
Status CreateUDG(ALGraph *G)
{
	printf("请输入顶点数和边数:");
	scanf("%d %d",&(*G).vexnum,&(*G).arcnum);    //输入顶点数和边数 
	printf("请输入%d顶点名称:",(*G).vexnum);    
	for(int i=0;i<(*G).vexnum;i++)
	{
		scanf(" %c",&((*G).vertices[i].data));   //输入图的顶点名称 
		(*G).vertices[i].firstarc = NULL;        //顶点表指向边链表指针初始化为NULL 
	}
	for(int k=0;k<(*G).arcnum;k++)
	{
		int i,j;
		char v1,v2;     //两个顶点
		printf("请输入连接那条边的两个顶点:");
		scanf(" %c%c",&v1,&v2);
		i=LocateVex(*G,v1);      //定位两个顶点的位置 
		j=LocateVex(*G,v2);
		ArcNode *p1 = (ArcNode *)malloc(sizeof(ArcNode));   //开辟一个结点加到 边链表里 
		p1->nextarc = (*G).vertices[i].firstarc;    //边链表新加入结点插到头 
		p1->adjvex = j;       //将边的另一个顶点位置设置为j
		p1->info = 1;         //权值 
		(*G).vertices[i].firstarc = p1;   //顶点连接边链表 
//		//无向网另一顶点
//		ArcNode *p2 = (ArcNode *)malloc(sizeof(ArcNode));
//		p2->nextarc = (*G).vertices[j].firstarc;
//		p2->adjvex = i;
//		p2->info = 1;
//		(*G).vertices[j].firstarc = p2;		
	}
	return OK;
}

代码在创建无向图的基础上注释掉后面几行就可以了,表示单向边链表。

深度遍历结果

在这里插入图片描述

创建有向网

创建这样一个又向网。
在这里插入图片描述

代码表示

在创建无向网的基础上注释掉后面几行。

//创建无向网 
Status CreateUDG(ALGraph *G)
{
	printf("请输入顶点数和边数:");
	scanf("%d %d",&(*G).vexnum,&(*G).arcnum);    //输入顶点数和边数 
	printf("请输入%d顶点名称:",(*G).vexnum);    
	for(int i=0;i<(*G).vexnum;i++)
	{
		scanf(" %c",&((*G).vertices[i].data));   //输入图的顶点名称 
		(*G).vertices[i].firstarc = NULL;        //顶点表指向边链表指针初始化为NULL 
	}
	for(int k=0;k<(*G).arcnum;k++)
	{
		int i,j;
		char v1,v2;     //两个顶点
		printf("请输入连接那条边的两个顶点:");
		scanf(" %c%c",&v1,&v2);
		i=LocateVex(*G,v1);      //定位两个顶点的位置 
		j=LocateVex(*G,v2);
		ArcNode *p1 = (ArcNode *)malloc(sizeof(ArcNode));   //开辟一个结点加到 边链表里 
		p1->nextarc = (*G).vertices[i].firstarc;    //边链表新加入结点插到头 
		p1->adjvex = j;       //将边的另一个顶点位置设置为j
		scanf("%d",&p1->info); 
		(*G).vertices[i].firstarc = p1;   //顶点连接边链表 
		//无向网另一顶点
//		ArcNode *p2 = (ArcNode *)malloc(sizeof(ArcNode));
//		p2->nextarc = (*G).vertices[j].firstarc;
//		p2->adjvex = i;
//		p2->info = p1->info;
//		(*G).vertices[j].firstarc = p2;		
	}
	return OK;
}

深度遍历结果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值