#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <limits.h>
#define MAX_VERTEX_NUM 20 //最大顶点个数
#define INFINITY INT_MAX //最大值∞
typedef char VertexType; //顶点向量类型
typedef int VRType;
typedef int InfoType;
typedef int QElemType;
//图的数组存储表示
typedef struct{
VertexType vexs[MAX_VERTEX_NUM]; //顶点向量
VRType arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM];; //邻接矩阵,于无权图1、0表示两个顶点是否相邻,对于有权图为权值
int vexnum,arcnum; //图的顶点数和弧数
}MGraph;
bool visited[MAX_VERTEX_NUM]; //标记顶点是否被访问,访问为true,否则为false
//查找顶点在顶点向量中的位置
int locateVertex(MGraph umg, VertexType v)
{
int i;
for(i=0;i<umg.vexnum;i++)
{
if(v == umg.vexs[i])
return i;
}
return -1;
}
//创建无向(有向)无权图
createUMGraph(MGraph *umg)
{
int i,j,v;
char v1,v2;
printf("输入无权图的顶点数和边数\n");
scanf("%d %d",&(*umg).vexnum,&(*umg).arcnum);
for(v=0;v<(*umg).vexnum;v++)
visited[v] = false;
getchar();
printf("输入顶点名称\n");
for(v=0;v<(*umg).vexnum;v++)
{
printf("输入第%d个顶点名称:",v);
scanf("%c",&(*umg).vexs[v]);
getchar();
}
//初始化邻接矩阵
for(i=0;i<(*umg).vexnum;i++)
for(j=0;j<(*umg).vexnum;j++)
(*umg).arcs[i][j] = 0;
//将图中相邻的顶点的邻接矩阵值设为1,不相邻仍为0
printf("输入边的信息,输入边的两个顶点名称v1 v2\n");
for(v=0;v<(*umg).arcnum;v++)
{
printf("输入第%d条边两个顶点:",v);
scanf("%c %c",&v1,&v2);
getchar();
printf("\n");
i = locateVertex(*umg,v1);
j = locateVertex(*umg,v2);
// (*umg).arcs[i][j] = (*umg).arcs[j][i] = 1; //由于是无向图,因此一条边关联两个顶点
(*umg).arcs[i][j] = 1; //有向图,边为单向
}
}
//创建无向(有向)有权图
createMGraph(MGraph *mg)
{
int i,j,v,w;
char v1,v2;
printf("输入有权图的顶点数和边数\n");
scanf("%d %d",&(*mg).vexnum,&(*mg).arcnum);
for(v=0;v<(*mg).vexnum;v++)
visited[v] = false;
getchar();
printf("输入顶点名称\n");
for(v=0;v<(*mg).vexnum;v++)
{
printf("输入第%d个顶点名称:",v);
scanf("%c",&(*mg).vexs[v]);
getchar();
}
//初始化邻接矩阵
for(i=0;i<(*mg).vexnum;i++)
for(j=0;j<(*mg).vexnum;j++)
(*mg).arcs[i][j] = INFINITY;
//将图中相邻的顶点的邻接矩阵值设为边的权值
printf("输入边的信息,输入边的两个顶点名称和权值v1 v2 w\n");
for(v=0;v<(*mg).arcnum;v++)
{
printf("输入第%d条边两个顶点和权值:",v);
scanf("%c %c %d",&v1,&v2,&w);
getchar();
i = locateVertex(*mg,v1);
j = locateVertex(*mg,v2);
// (*mg).arcs[i][j] = (*mg).arcs[j][i] = w; //由于是无向图,因此一条边关联两个顶点
(*mg).arcs[i][j] = w; //有向图,边为单向
}
}
//打印图的临界矩阵
void print(MGraph G)
{
int i,j;
printf("图的邻接矩阵\n");
for(i=0;i<G.vexnum;i++)
{
for(j=0;j<G.vexnum;j++)
{
if(G.arcs[i][j]!=INFINITY)
printf("%d ",G.arcs[i][j]);
else
printf("∞ ");
}
printf("\n");
}
printf("\n");
}
//深度优先遍历图
int FirstAdjVex(MGraph G,int v)
{ //获取与顶点v相邻的第一个顶点下标
int i;
for(i=0;i<G.vexnum;i++)
{
if(G.arcs[v][i]!=0 && G.arcs[v][i]!=INFINITY && !visited[i])
return i;
}
return -1;
}
int NextAdjVex(MGraph G,int v,int w)
{ //得到v的下一个未被访问的相邻顶点下标
int i;
for(i=w;i<G.vexnum;i++)
{
if(G.arcs[v][i]!=0 && G.arcs[v][i]!=INFINITY && !visited[i])
return i;
}
return -1;
}
void DFS(MGraph G,int v)
{
int w;
visited[v] = true;
printf("%c ",G.vexs[v]); //访问第v个顶点
for(w = FirstAdjVex(G,v); w >= 0;w = NextAdjVex(G,v,w))
if(!visited[w])
DFS(G,w); //对v的尚未访问的邻接顶点w递归调用DFS
}
void DFSTraverse(MGraph G)
{
printf("深度优先遍历序列:");
int v;
for(v = 0; v<G.vexnum;v++)
visited[v] = false;
for(v=0;v<G.vexnum;v++)
if(!visited[v])
DFS(G,v);
printf("\n");
}
//广度优先遍历
//创建用于广度优先遍历的队列
typedef struct QNode
{
QElemType data;
struct QNode *qnext;
}QNode,*PQNode;
typedef struct Queue
{
PQNode front;
PQNode rear;
}Queue,*PQueue;
//初始化一个空队列
PQueue initQueue()
{
PQueue pqueue = (PQueue)malloc(sizeof(Queue));
PQNode pqnode = (PQNode)malloc(sizeof(QNode));
if(pqnode==NULL)
{
printf("队列头空间申请失败!\n");
exit(-1);
}
pqueue->front = pqueue->rear = pqnode;
pqnode->qnext = NULL;
return pqueue;
}
//队尾入队
void enQueue(PQueue pqueue,QElemType data)
{
PQNode pqnode = (PQNode)malloc(sizeof(QNode));
if(pqnode==NULL)
{
printf("队列结点申请失败!\n");
exit(-1);
}
pqnode->data = data;
pqnode->qnext = NULL;
pqueue->rear->qnext = pqnode;
pqueue->rear = pqnode;
}
//判断队列是否为空
bool isEmpty(PQueue pqueue)
{
if(pqueue->front == pqueue->rear)
return true;
return false;
}
//队头出队
QElemType deQueue(PQueue pqueue)
{
if(isEmpty(pqueue))
{
printf("队列为空\n");
exit(-1);
}
PQNode pqnode = pqueue->front->qnext;
pqueue->front->qnext = pqnode->qnext;
if(pqnode == pqueue->rear)
pqueue->rear = pqueue->front;
QElemType data = pqnode->data;
free(pqnode);
return data;
}
void BFSTraverse(MGraph G)
{
printf("广度优先遍历序列:");
int i,v,w;
for(i=0;i<G.vexnum;i++)
visited[i] = false;
PQueue pqueue = initQueue(); //初始化辅助队列
for(i=0;i<G.vexnum;i++)
{
if(!visited[i]) //i未被访问
{
visited[i] = true;
printf("%c ",G.vexs[i]);
enQueue(pqueue,i);
while(!isEmpty(pqueue))
{
v = deQueue(pqueue); //队头元素出队
for(w=FirstAdjVex(G,v);w>=0;w=NextAdjVex(G,v,w))
if(!visited[w]) //w为v的尚未访问的邻接顶点
{
visited[w] = true;
printf("%c ",G.vexs[w]);
enQueue(pqueue,w);
}
}
}
}
printf("\n");
}
int main()
{
// MGraph umg; //无权图
// createUMGraph(&umg); //创建无权图
// print(umg);
MGraph mg;
createMGraph(&mg);
print(mg);
DFSTraverse(mg);
BFSTraverse(mg);
return 0;
}
图的遍历(DFS、BFS)使用邻接矩阵(数组)作为存储结构--C语言
原文作者:数据结构之图
原文地址: https://blog.csdn.net/haofight/article/details/54585218
本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
原文地址: https://blog.csdn.net/haofight/article/details/54585218
本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。