数据结构——图的存储与遍历(邻接矩阵)

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

#define MAXVEX      20             /*最大顶点个数*/ 
#define INFINITY    32767          /*表示无穷,可自定义*/

#define Elem        int
#define FALSE       0
#define OK          1
#define TRUE        1

typedef char VertexType;

typedef struct{
	int arcs[MAXVEX][MAXVEX];            //邻接矩阵,边的信息
	VertexType vexs[MAXVEX];        //顶点信息 
	int vexnum;      //顶点数目 
	int arcnum;      //边(弧)数目 
	
}AdjMatrix; 

//根据名称得到指定顶点在顶点集合中的下标
int getIndexOfVexs(char vex,AdjMatrix *MG)
{
	for(int i=1;i<=MG->vexnum;i++)
	{
		if(MG->vexs[i]==vex) return i;
	}
	return 0;
}

//用邻接矩阵创建图 
void Create(AdjMatrix *MG){
	int v1,v2;
	char c1,c2;

	printf("请输入顶点数目: ");         //输入顶点数 
	scanf("%d",&MG->vexnum);
	printf("请输入边的数目: ");         //输入边数 
	scanf("%d",&MG->arcnum);
	getchar();
	
    //输入各顶点信息 
	for(int i=1;i<=MG->vexnum;i++)
	{
		printf("请输入第%d个顶点(char): ",i);    //请输入各顶点信息   
		scanf("%c",&MG->vexs[i]);
		getchar();
	}
	
	//初始化邻接矩阵
	for(int i=1;i<=MG->vexnum;i++)
		for (int j=1;j<=MG->vexnum;j++)
			MG->arcs[i][j]=0;               /*如果是网则赋值INFINITY */ 
			
	//输入边的信息,建立邻接矩阵
	for(int k=1;k<=MG->arcnum;k++)
	{
		printf("请输入第%d个边连接的两个顶点v1(char) v2(char): ",k);  //请输入有关系的两个顶点 
		scanf("%c %c",&c1,&c2);
		v1=getIndexOfVexs(c1,MG);
		v2=getIndexOfVexs(c2,MG);
		MG->arcs[v1][v2]=1; 
		MG->arcs[v2][v1]=1;   //无向图为对称矩阵
		getchar();
	}
}

//打印图的信息 
void Printf(AdjMatrix MG)
{
	printf("顶点数目为: %d\n",MG.vexnum);
	printf("边的数目为: %d\n",MG.arcnum);
	printf("顶点: ");
	for(int i=1;i<=MG.vexnum;i++)
		printf("%c",MG.vexs[i]);
		
	printf("\n邻接矩阵为: \n");
	for(int i=1;i<=MG.vexnum;i++)
	{
		for(int j=1;j<=MG.vexnum;j++)
			printf("%d",MG.arcs[i][j]);
			
		printf("\n");
	}
}

/******************递归深度优先遍历函数***********************/
void visit(AdjMatrix G,int v){
		printf("%c",G.vexs[v]);
}

int FirstAdjVex(AdjMatrix G,int v){    //寻找图G中v的第一个邻接点
	 for(int i=1;i<=G.vexnum;i++){
	 	if(G.arcs[v][i]!=0) return i;
	 }
	 return -1;
}
 
int NextAdjVex(AdjMatrix G,int v,int w){   //寻找图G中v顶点在w之后的下一个邻接点
	 for(int i=w+1;i<=G.vexnum;i++){
	 	if(G.arcs[v][i]!=0) return i;
	 }
	 return -1;
} 

int visited[MAXVEX]={0};  //访问标志数组
void DFS(AdjMatrix G,int v){   //递归深度优先遍历连通子图 
	visit(G,v);    //查看v; 
	visited[v]=1;
	int w=FirstAdjVex(G,v);  //图G中v的第一个邻接点 
	while(w!=-1){  //如果没有邻接点则返回-1
		if(!visited[w]) DFS(G,w); //如果w没有被访问过,则对w进行深度优先遍历 
		w=NextAdjVex(G,v,w);    //寻找图G中v的下一个邻接点 
	} 
} 

void TraverseG(AdjMatrix G){    //深度优先遍历图 
	for(int v=1;v<=G.vexnum;v++)  //标志数组初始化 
		visited[v]=0;
	printf("\n深度优先遍历:");	
	for(int v=1;v<=G.vexnum;v++){
		if(!visited[v]) DFS(G,v);
	}	
}


/*******************广度优先遍历函数(相似与二叉树的层次遍历)***********************/
              /********队列函数*******/
 typedef struct array{      //定义队列结构 
 	Elem elem;
 	struct array *next;
 }*PLArray; 
 
 typedef struct Node_D{
 	PLArray  front;   //指向队头 
 	PLArray  rear;    //指向队尾 
 	int len;          //队列实际长度 
 }*pNode;
 
void InitArray(pNode &S){    //构造空队列 
	PLArray q=(PLArray)malloc(sizeof(PLArray)); //申请新结点
	S=(pNode)malloc(sizeof(pNode)); 
	S->front=q;
	S->rear=q;
	S->front->next=NULL;
	S->len=0; 
	
}

int Push(pNode &S,Elem e){    //插入数据e为队列的队尾 
	PLArray p=(PLArray)malloc(sizeof(PLArray));  //申请新结点 
	p->elem=e;
	
	p->next=NULL;
	S->rear->next=p;   //将结点插入到队尾 
	S->rear=p;         //修改队尾指针 
	S->len++; 
}

int Pop(pNode &S,Elem &e){    //删除队头元素,,用e返回其删除数据 
	if(S->front==S->rear)  return FALSE;
	PLArray p=S->front->next;   //p指向队头
	e=p->elem;
	S->front->next=p->next;   //修改头结点的指针域
	if(S->rear==p) S->rear=S->front;   //最后元素被删除
	S->len--;
	return OK ;
}

int ArrayEmpty(pNode &S){    //判断队列是否为空 
	if(S->len==0)  return TRUE;
	else           return FALSE;
} 

int Refer(pNode &S,Elem &e) {  //查询队头元素 
	e=S->front->next->elem;
}

/*广度优先遍历的 visit函数,FirstAdjVex函数,NextAdjVex函数  功能相同不重复定义 */
int visited2[MAXVEX]={0};  //访问标志数组
void BFS(AdjMatrix G,int v){  //广度优先遍历连通子图
	visit(G,v);
	visited2[v]=1;
	pNode Q;
	InitArray(Q);  //创建空队列
	Push(Q,v);     //入队
	while(!ArrayEmpty(Q)){    //当队列非空时
		Pop(Q,v);     //出队
		int w=FirstAdjVex(G,v);  //图G中v的第一个邻接点
		while(w!=-1){            //遍历v的所有邻接点 
			if(!visited2[w]){
				visit(G,w);
				visited2[w]=1;
				Push(Q,w);
			}
			w=NextAdjVex(G,v,w);    //寻找图G中v的下一个邻接点
		} 
		 
	}	 
} 

void TraverseG_2(AdjMatrix G){    //广度优先遍历图 
	for(int v=1;v<=G.vexnum;v++)  //标志数组初始化 
		visited2[v]=0;
	printf("\n广度优先遍历:");	
	for(int v=1;v<=G.vexnum;v++){
		if(!visited2[v]) BFS(G,v);
	}	
}

int main(){
	AdjMatrix MG;
	Create(&MG); 
	Printf(MG);
	TraverseG(MG);
	TraverseG_2(MG);
	return 0;
}
    原文作者:数据结构之图
    原文地址: https://blog.csdn.net/qq_41596568/article/details/84586569
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞