C语言实现图的邻接表

笔者通过纯C语言实现图的邻接表表示法

(单向有权图)

涉及操作有:
图顶点的 增 删 改 查
图边的 增 删 改 查
打印邻接表
迪杰斯特拉算法 求最短路径(包括中转节点的记录)

部分原理限于篇幅会做介绍,但关键在于自己搜寻资料学习
此博客目的在于分享心得

源代码在文章最后,直接可用

图的原理构造(篇末源代码也是复现如此结构)如下:

在这里插入图片描述
注意:此结构进行过改动,会与部分图书有出入。
因为涉及图顶点(节点)的增删改查,故对顶点的结构进行改动,从原来的数组实现改为单链表实现。
基于数组实现的邻接表也可以实现图节点的增删改查,但过于麻烦,笔者没有采用

源代码结构体说明(typedef用法自行百度):

顶点(Vertex)的结构体
包含顶点的名字 name
指向下一顶点的指针域 next_vertex
指向出边的指针域 out

typedef struct vertex
{
	char name;
	struct vertex *next_vertex;
	struct arc *out;
}Vertex;

边(Arc)的结构体
包含边的权重 weight
指向下一条边的指针域 next_arc
指向终点的指针域 adjvex

typedef struct arc
{
	int weight;
	struct vertex * adjvex;
	struct arc *next_arc;
}Arc;

图(Graph)的结构体
包含图的顶点数量 vertex_num
图的边的数量 arc_next
邻接表的头节点 head

typedef struct graph
{
	int vertex_num;
	int arc_num;
	struct vertex * head;
}Graph;

栈的结构体 迪杰斯特拉算法记录中转节点要用到

typedef struct stack	
{
	int top;
	int save[100];
}Stack;		

功能函数声明:

Vertex * Creat_Vertex();			// 开辟节点空间并初始化 
Arc * Creat_Arc(); 					// 开辟边空间并初始化 
Graph * Creat_Graph();				// 开辟图空间并初始化 
Vertex * Serch_Vertex(Graph * g , char name);		// 返回指定名字节点的地址 节点不存在则返回空 
Arc * Serch_Arc(Graph *g , char beg , char end);	// 返回指定名字边的地址 边不存在则返回空 
void Change_Vertex(Graph *g , char name,char name_new);		// 改变节点的名字 
void Change_Arc(Graph *g , char beg , char end , int weight);	// 改变边的权重 
void Del_Arc(Graph *g ,char beg ,char end );	// 删除边 
void Del_Vertex(Graph *g ,char name);		// 删除节点(包括于节点有关的所有的边的删除) 
void Add_Vertex(Graph *g , char name);		// 添加节点 
void Add_Arc(Graph *g , char beg , char end , int weight);	// 添加边 包括 beg->end 和 end->beg 
void Display(Graph *g);		// 打印邻接表 

部分函数说明:

开辟空间函数
为指定类型的结构体动态分配空间,并初始化

Vertex * Creat_Vertex()
{
	Vertex * v = (Vertex*)malloc(sizeof(Vertex));
	v->out = NULL;			// 指向出边
	v->next_vertex = NULL;		//指向下一顶点
	return v;
}

Arc * Creat_Arc()
{
	Arc * a = (Arc*)malloc(sizeof(Arc));
	a->weight = 0;
	a->adjvex = NULL;
	a->next_arc = NULL;
	return a;
}

Graph * Creat_Graph()
{
	Graph * g = (Graph*)malloc(sizeof(Graph));
	g->vertex_num = 0;
	g->arc_num = 0;
	g->head = NULL;
	return g;
}

查找函数的实现

顶点的查找只需要遍历顶点链表即可
若存在返回其所在地址,若不存在返回NULL
而边的查找,则需要起点(beg)和终点(end)
通过 Serch_Vertex函数 查找起点所在的位置,通过遍历起点的所有出边,即可定位到指定的边。

Vertex * Serch_Vertex(Graph * g , char name)
{
	Vertex * v = g->head;
	for(v=g->head ; v ; v=v->next_vertex)
	{
		if(v&&v->name==name)
			return v;
	}
	return NULL;
}

Arc * Serch_Arc(Graph *g , char beg , char end)
{
	Arc * a=NULL;
	Vertex * beg_v, *end_v;
	beg_v = Serch_Vertex(g,beg);	//获取起点位置
	end_v = Serch_Vertex(g,end);	// 获取终点位置
	if(beg_v&&end_v)	// 仅当起点 终点同时存在时继续
	{
		for(a=beg_v->out ; a ; a=a->next_arc)		// 通过起点的出边 查找指向终点 的边
		{
			if(a->adjvex->name == end)
				return a;
		}
		return NULL;	
	}
	else
	{
		return NULL;
	}
}

节点名称和边权重的修改

修改的操作基于查找就能简单实现
注意
修改A->B的线路长度时 也同时 要修改B->A的线路长度(因为是单向有权图)

void Change_Vertex(Graph *g , char name,char name_new)	// name是要修改节点的名称 new_name是修改后新的名称
{
	Vertex * v=NULL,*v1=NULL;
	v=Serch_Vertex(g,name);
	v1=Serch_Vertex(g,name_new);
	if( v&& v1==NULL)
	{
		v->name = name_new;
	}
	else
	{
		printf("Pease check repeat or dose it exist!\n");
		return ;
	}
}

void Change_Arc(Graph *g , char beg , char end , int weight)
{
	Arc * a=NULL;
	if(a=Serch_Arc(g,beg,end))
	{
		a->weight = weight;
		
		a = Serch_Arc(g,end,beg);
		a->weight = weight;
		 
		return ;
	}
	else
	{
		printf("arc is not exist!\n");
		return ;
	}
}

顶点和边的删除

边的删除也要删除A->B 和 B->A的线路
顶点的删除较为麻烦
首先 邻接表中所有指向顶点的边都要删除(通过边的删除实现,即删除终点为顶点的所有边)
其次 要从顶点链表中删除顶点(删除该顶点的同时,所有起点为该顶点的边全部删除)

void Del_Arc(Graph *g ,char beg ,char end )			//删除边也是 A->B 和 B->A都要同时删除 
{
		
	Arc * a1=NULL , *a2=NULL;
	Vertex * v,*v1;
	v = Serch_Vertex(g,beg);

	a1 = Serch_Arc(g,beg,end);		
	if(a1)
	{		
		for(a2=v->out ; a2 ; a1=a2 , a2=a2->next_arc)
		{
			if(a2->adjvex->name==end)
			{
				if(a2==v->out)			// 头节点特判 
				{
					v->out = a2->next_arc;
					free(a2);
				}
				else
				{
					a1->next_arc = a2->next_arc;
					free(a2);
				}
			}
		}
		g->arc_num -= 1;
		Del_Arc(g ,end ,beg );	
	}
	else
	{
		//printf("arc is not exist!\n");
		return ;
	}
}

void Del_Vertex(Graph *g ,char name)			// 删除顶点需要删除与顶点有关的所有边 
{
	Vertex *v1=NULL,*v2=NULL;
	Arc *a=NULL;
	int count=0;

	for(v1=g->head ; v1 ; v1=v1->next_vertex)		// 删除终点为顶点的边 和顶点所有的出边 
	{
		if(v1->name!=name)
		Del_Arc(g,v1->name,name);
	}
	v1=Serch_Vertex(g,name);
	if(v1)					// 删除起点的顶点(起点的消失,导致所有起点为顶点的边也消失) 
	{
		if(v1==g->head)
		{
			g->head = v1->next_vertex;
			free(v1);
		}
		else 
		for(v2=g->head ; v2->next_vertex ; v2=v2->next_vertex)
		{
			if(v2->next_vertex==v1)
			{
				v2->next_vertex = v1->next_vertex;
				free(v1);
				break;
			}
		} 
		
		g->vertex_num -= 1;
	}	
	else
	{
		printf("vertex not exist!\n");
		return ;
	}
}

顶点和边的添加

添加实现较为容易,本质就是单链表指定位置的插入
同时注意一些错误机制 类似于重复添加的检查机制

void Add_Vertex(Graph *g , char name)				// 基于单链表的头插法实现 
{
	Vertex * v=NULL;
	v = Serch_Vertex(g,name);
	if(!v)
	{
		v = Creat_Vertex();
		v->name = name;
		v->next_vertex = g->head;
		g->head = v;
		
		g->vertex_num += 1;			// 顶点数+1 
		return ;	
	}
	else
	{
		printf("vertex is repeat !\n");
		return ;
	}
} 

void Add_Arc(Graph *g , char beg , char end , int weight)		// 同样两条边都要添加 操作基于顶点的查找函数实现 
{
	Arc *a=NULL;
	Vertex * v=NULL,*v1=NULL;
	a = Serch_Arc(g,beg,end);
	v = Serch_Vertex(g,beg);
	v1 = Serch_Vertex(g,end);
	if(!v)						// 如果指定顶点不存在 就将其添加至邻接表中 
		Add_Vertex(g,beg);			
	if(!v1)
		Add_Vertex(g,end);
		
	if(!a)
	{
		v = Serch_Vertex(g,beg);		// 开辟边的空间 
		v1 = Serch_Vertex(g,end);
		
		a = Creat_Arc();			// 添加 beg->end 
		a->weight = weight;
		a->next_arc = v->out;
		v->out = a;
		a->adjvex = v1;
		
		a = Creat_Arc();		//  添加end->beg 
		a->weight = weight;
		a->next_arc = v1->out;
		v1->out = a;
		a->adjvex = v;
		
		g->arc_num += 2;
		return ;
	}
	else
	{
		printf("arc is exist !");
		return ;
	}
}

获取权重

int Get_weight(Graph *g ,char beg , char end )
{
	if(beg == end)
	return 0;
	
	Arc * a = Serch_Arc(g,beg,end);
	if(a)
	{
		return a->weight;
	}
	else
		return INF;
}

迪杰斯特拉算法

迪杰斯特拉算法基于图的邻接矩阵实现(大部分)

笔者这里通过邻接表实现了
所以进行了些许修改,需要用 list 数组记录节点的地址(并记录起点 终点)
实现代码核心不会有太大变化,其中获取两个点的距离用get_weight函数实现

中转节点的记录用save数组记录,但由于是逆序的,所以用栈stack的操作将之顺序

void Dijkstra(Graph *g , char beg , char end )		
{
	if(!Serch_Vertex(g,beg)||!Serch_Vertex(g,end))
	{
		printf("Wrong\n");
		return ;
	} 
	
	
	Vertex ** list = (Vertex**)malloc(g->vertex_num*sizeof(Vertex*));
	Vertex * ver;
	int index_beg,index_end;
	int i,j,k,v,u;
	
	Stack st;
	st.top = -1;
	
	for(ver=g->head, i=1 ; i<=g->vertex_num ; i++)			// 将节点地址记录到list数组中 并标记起点 终点 在数组的下标 
	{
		list[i] = ver;
		if(ver->name==beg)	 index_beg = i;
		if(ver->name==end)	 index_end = i;
		ver = ver->next_vertex;
	}
	
	for(i=1; i<=g->vertex_num ;i++)
	{
		
		dis[i] = Get_weight(g,beg,list[i]->name);			// get_weight 获取起点到终点的长度  
		mask[i] = 0;		
		save[i] = -1;										// 记录中转城市的save数组初始化 
	}
	
	
	//Dijkstra 核心语句
	mask[index_beg] = 1;			//标记起点 
	for(i=0 ; i<=g->vertex_num ; i++)
	{
		int min = INF;
		for(j=1 ; j<=g->vertex_num ; j++)
		{
			if(mask[j]==0 && dis[j]<min)
			{
				min = dis[j];
				u = j;
			}
		}
		mask[u] = 1;			 
		for(v=1 ; v<=g->vertex_num ; v++)
		{
			if(Get_weight(g,list[u]->name,list[v]->name)<INF)
			{
				if(dis[v] > dis[u]+Get_weight(g,list[u]->name,list[v]->name))
				{
					dis[v] = dis[u]+Get_weight(g,list[u]->name,list[v]->name);
					save[v] = u;
				}
			}
		}
	}
	
	i = index_end;
	while(save[i]!=-1)
	{
		st.top ++;
		st.save[st.top] = save[i];
		i = save[i];
	}
	if(dis[index_end]==INF)
		printf("没有联通的路\n");
	else
	{
		printf("经计算 %c->%c 最短路径为:%d \n",beg,end,dis[index_end]);
		printf("路径为:\n");
		printf("%c->",list[index_beg]->name);			//打印起点 
		while(st.top != -1)
		{
			printf("%c->",list[st.save[st.top]]->name);		// 打印中转城市
			st.top -= 1; 
		} 
		printf("%c",list[index_end]->name);				//打印终点 
		printf("\n");	
		printf("\n");	
	} 
}

邻接表的打印

打印邻接表

void Display(Graph *g)
{
	Vertex *c = g->head;
	for(c ; c ; c=c->next_vertex)
	{
		printf("%c",c->name);
		if(c->out)
		{	printf("-->");
			Arc *p = c->out;
			for(p ; p ;p=p->next_arc)
			{
				printf("%c",p->adjvex->name);
				if(p->next_arc)
					printf("-->");
			}
			printf("\n");
		}
		else
			printf("\n");
	}
	printf("Vertex_num :%d   Arc_num :%d\n",g->vertex_num,g->arc_num); 
}

测试用main函数

int main()
{
	Graph *g = Creat_Graph();
	int i,j; 
	char s[]={"ABCDEFG"};
	for(i=0 ; i<7 ; i++)
	{
		Add_Vertex(g,s[i]);
	}
	
	// 插入边 
	Add_Arc(g,'A','B',12);
	Add_Arc(g,'A','R',19);
	Add_Arc(g,'C','F',8);
	Add_Arc(g,'B','R',3);
	
	// 删除节点 A 
	//Del_Vertex(g,'A');
	
	Dijkstra(g,'A','R');			// A 到 R 的最短路 
	
	Display(g);	
	return 0;
}

源代码:

#include<stdio.h>
#include<stdlib.h>
#define INF 99999

int dis[100]={0};
int mask[100]={0};
int save[100]={0};

typedef struct vertex
{
	char name;
	struct vertex *next_vertex;
	struct arc *out;
}Vertex;

typedef struct arc
{
	int weight;
	struct vertex * adjvex;
	struct arc *next_arc;
}Arc;

typedef struct graph
{
	int vertex_num;
	int arc_num;
	struct vertex * head;
}Graph;

typedef struct stack	
{
	int top;
	int save[100];
}Stack;		


Vertex * Creat_Vertex();			// 开辟节点空间并初始化 
Arc * Creat_Arc(); 					// 开辟边空间并初始化 
Graph * Creat_Graph();				// 开辟图空间并初始化 
Vertex * Serch_Vertex(Graph * g , char name);		// 返回指定名字节点的地址 节点不存在则返回空 
Arc * Serch_Arc(Graph *g , char beg , char end);	// 返回指定名字边的地址 边不存在则返回空 
void Change_Vertex(Graph *g , char name,char name_new);		// 改变节点的名字 
void Change_Arc(Graph *g , char beg , char end , int weight);	// 改变边的权重 
void Del_Arc(Graph *g ,char beg ,char end );	// 删除边 
void Del_Vertex(Graph *g ,char name);		// 删除节点(包括于节点有关的所有的边的删除) 
void Add_Vertex(Graph *g , char name);		// 添加节点 
void Add_Arc(Graph *g , char beg , char end , int weight);	// 添加边 包括 beg->end 和 end->beg 
int Get_weight(Graph *g , char beg , char end);			// 获取边的权值 
void Dijkstra(Graph *g , char beg,char end); 		// 迪杰斯特拉最短路算法  包括打印路径 
void Display(Graph *g);		// 打印邻接表 



Vertex * Creat_Vertex()
{
	Vertex * v = (Vertex*)malloc(sizeof(Vertex));
	v->out = NULL;
	v->next_vertex = NULL;
	return v;
}

Arc * Creat_Arc()
{
	Arc * a = (Arc*)malloc(sizeof(Arc));
	a->weight = 0;
	a->adjvex = NULL;
	a->next_arc = NULL;
	return a;
}

Graph * Creat_Graph()
{
	Graph * g = (Graph*)malloc(sizeof(Graph));
	g->vertex_num = 0;
	g->arc_num = 0;
	g->head = NULL;
	return g;
}

Vertex * Serch_Vertex(Graph * g , char name)
{
	Vertex * v = g->head;
	for(v=g->head ; v ; v=v->next_vertex)
	{
		if(v&&v->name==name)
			return v;
	}
	return NULL;
}

Arc * Serch_Arc(Graph *g , char beg , char end)
{
	Arc * a=NULL;
	Vertex * beg_v, *end_v;
	beg_v = Serch_Vertex(g,beg);
	end_v = Serch_Vertex(g,end);
	if(beg_v&&end_v)
	{
		for(a=beg_v->out ; a ; a=a->next_arc)
		{
			if(a->adjvex->name == end)
				return a;
		}
		return NULL;	
	}
	else
	{
		return NULL;
	}
}

void Change_Vertex(Graph *g , char name,char name_new)
{
	Vertex * v=NULL,*v1=NULL;
	v=Serch_Vertex(g,name);
	v1=Serch_Vertex(g,name_new);
	if( v&& v1==NULL)
	{
		v->name = name_new;
	}
	else
	{
		printf("Pease check repeat or dose it exist!\n");
		return ;
	}
}

void Change_Arc(Graph *g , char beg , char end , int weight)
{
	Arc * a=NULL;
	if(a=Serch_Arc(g,beg,end))
	{
		a->weight = weight;
		
		a = Serch_Arc(g,end,beg);
		a->weight = weight;
		 
		return ;
	}
	else
	{
		printf("arc is not exist!\n");
		return ;
	}
}

void Del_Arc(Graph *g ,char beg ,char end )			//删除边也是 A->B 和 B->A都要同时删除 
{
		
	Arc * a1=NULL , *a2=NULL;
	Vertex * v,*v1;
	v = Serch_Vertex(g,beg);

	a1 = Serch_Arc(g,beg,end);		
	if(a1)
	{		
		for(a2=v->out ; a2 ; a1=a2 , a2=a2->next_arc)
		{
			if(a2->adjvex->name==end)
			{
				if(a2==v->out)			// 头节点特判 
				{
					v->out = a2->next_arc;
					free(a2);
				}
				else
				{
					a1->next_arc = a2->next_arc;
					free(a2);
				}
			}
		}
		g->arc_num -= 1;	
		Del_Arc(g ,end ,beg );	
	}
	
	else
	{
		//printf("arc is not exist!\n");
		return ;
	}
}

void Del_Vertex(Graph *g ,char name)			// 删除顶点需要删除与顶点有关的所有边 
{
	Vertex *v1=NULL,*v2=NULL;
	Arc *a=NULL;
	int count=0;

	for(v1=g->head ; v1 ; v1=v1->next_vertex)		// 删除终点为顶点的边 和顶点所有的出边 
	{
		if(v1->name!=name)
		Del_Arc(g,v1->name,name);
	}
	v1=Serch_Vertex(g,name);
	if(v1)					// 删除起点的顶点(起点的消失,导致所有起点为顶点的边也消失) 
	{
		if(v1==g->head)
		{
			g->head = v1->next_vertex;
			free(v1);
		}
		else 
		for(v2=g->head ; v2->next_vertex ; v2=v2->next_vertex)
		{
			if(v2->next_vertex==v1)
			{
				v2->next_vertex = v1->next_vertex;
				free(v1);
				break;
			}
		} 
		
		g->vertex_num -= 1;
	}	
	else
	{
		printf("vertex not exist!\n");
		return ;
	}
}



void Add_Vertex(Graph *g , char name)				// 基于单链表的头插法实现 
{
	Vertex * v=NULL;
	v = Serch_Vertex(g,name);
	if(!v)
	{
		v = Creat_Vertex();
		v->name = name;
		v->next_vertex = g->head;
		g->head = v;
		
		g->vertex_num += 1;			// 顶点数+1 
		return ;	
	}
	else
	{
		printf("vertex is repeat !\n");
		return ;
	}
} 

void Add_Arc(Graph *g , char beg , char end , int weight)		// 同样两条边都要添加 操作基于顶点的查找函数实现 
{
	Arc *a=NULL;
	Vertex * v=NULL,*v1=NULL;
	a = Serch_Arc(g,beg,end);
	v = Serch_Vertex(g,beg);
	v1 = Serch_Vertex(g,end);
	if(!v)						// 如果指定顶点不存在 就将其添加至邻接表中 
		Add_Vertex(g,beg);			
	if(!v1)
		Add_Vertex(g,end);
		
	if(!a)
	{
		v = Serch_Vertex(g,beg);		// 开辟边的空间 
		v1 = Serch_Vertex(g,end);
		
		a = Creat_Arc();			// 添加 beg->end 
		a->weight = weight;
		a->next_arc = v->out;
		v->out = a;
		a->adjvex = v1;
		
		a = Creat_Arc();		//  添加end->beg 
		a->weight = weight;
		a->next_arc = v1->out;
		v1->out = a;
		a->adjvex = v;
		
		g->arc_num += 2;
		return ;
	}
	else
	{
		printf("arc is exist !");
		return ;
	}
}

void Display(Graph *g)
{
	Vertex *c = g->head;
	for(c ; c ; c=c->next_vertex)
	{
		printf("%c",c->name);
		if(c->out)
		{	printf("-->");
			Arc *p = c->out;
			for(p ; p ;p=p->next_arc)
			{
				printf("%c",p->adjvex->name);
				if(p->next_arc)
					printf("-->");
			}
			printf("\n");
		}
		else
			printf("\n");
	}
	printf("Vertex_num :%d   Arc_num :%d\n",g->vertex_num,g->arc_num); 
}


int Get_weight(Graph *g ,char beg , char end )
{
	if(beg == end)
	return 0;
	
	Arc * a = Serch_Arc(g,beg,end);
	if(a)
	{
		return a->weight;
	}
	else
		return INF;
}


void Dijkstra(Graph *g , char beg , char end )		
{
	if(!Serch_Vertex(g,beg)||!Serch_Vertex(g,end))
	{
		printf("Wrong\n");
		return ;
	} 
	
	
	Vertex ** list = (Vertex**)malloc(g->vertex_num*sizeof(Vertex*));
	Vertex * ver;
	int index_beg,index_end;
	int i,j,k,v,u;
	
	Stack st;
	st.top = -1;
	
	for(ver=g->head, i=1 ; i<=g->vertex_num ; i++)			// 将节点地址记录到list数组中 并标记起点 终点 在数组的下标 
	{
		list[i] = ver;
		if(ver->name==beg)	 index_beg = i;
		if(ver->name==end)	 index_end = i;
		ver = ver->next_vertex;
	}
	
	for(i=1; i<=g->vertex_num ;i++)
	{
		
		dis[i] = Get_weight(g,beg,list[i]->name);			// get_weight 获取起点到终点的长度  
		mask[i] = 0;		
		save[i] = -1;										// 记录中转城市的save数组初始化 
	}
	
	
	//Dijkstra 核心语句
	mask[index_beg] = 1;			//标记起点 
	for(i=0 ; i<=g->vertex_num ; i++)
	{
		int min = INF;
		for(j=1 ; j<=g->vertex_num ; j++)
		{
			if(mask[j]==0 && dis[j]<min)
			{
				min = dis[j];
				u = j;
			}
		}
		mask[u] = 1;			 
		for(v=1 ; v<=g->vertex_num ; v++)
		{
			if(Get_weight(g,list[u]->name,list[v]->name)<INF)
			{
				if(dis[v] > dis[u]+Get_weight(g,list[u]->name,list[v]->name))
				{
					dis[v] = dis[u]+Get_weight(g,list[u]->name,list[v]->name);
					save[v] = u;
				}
			}
		}
	}
	
	i = index_end;
	while(save[i]!=-1)
	{
		st.top ++;
		st.save[st.top] = save[i];
		i = save[i];
	}
	if(dis[index_end]==INF)
		printf("没有联通的路\n");
	else
	{
		printf("经计算 %c->%c 最短路径为:%d \n",beg,end,dis[index_end]);
		printf("路径为:\n");
		printf("%c->",list[index_beg]->name);			//打印起点 
		while(st.top != -1)
		{
			printf("%c->",list[st.save[st.top]]->name);		// 打印中转城市
			st.top -= 1; 
		} 
		printf("%c",list[index_end]->name);				//打印终点 
	
		printf("\n");
		printf("\n");		
	} 
}

int main()
{
	Graph *g = Creat_Graph();
	int i,j; 
	char s[]={"ABCDEFG"};
	for(i=0 ; i<7 ; i++)
	{
		Add_Vertex(g,s[i]);
	}
	
	// 插入边 
	Add_Arc(g,'A','B',12);
	Add_Arc(g,'A','R',19);
	Add_Arc(g,'C','F',8);
	Add_Arc(g,'B','R',3);
	
	// 删除节点 A 
	//Del_Vertex(g,'A');
	
	Dijkstra(g,'A','R');			// A 到 R 的最短路 
	
	Display(g);	
	return 0;
}

运行截图:
在这里插入图片描述笔者后续会更新 DFS BFS 图的邻接表的算法实现
谢谢观看~

  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值