大学程序实验.数据结构.图型结构的应用二.邻接矩阵二
- 2 下一章
0 目录
5 图型结构的应用
5.2 邻接矩阵二
5.2.1 题目
1、图的建立
从键盘输入数据建立图,并打印
实验要求:在程序中定义下述函数,并实现要求的函数功能:
CreateGraph(): 按从键盘输入数据建立图
PrintGrah():打印图
实验提示:
图的存储可采用邻接矩阵或邻接表;
打印出每一个顶点信息和邻接矩阵或邻接表
注意问题:
有向图,无向图,有向网,无向网任选一种。
2、深度优先遍历以及广度优先遍历
问题描述:从键盘输入数据建立图并打印深度优先遍历序列和广度优先遍历序列。
实验提示:
图的存储可采用邻接矩阵或邻接表;
有向图,无向图,有向网,无向网任选一种。
5、求一条从顶点 v 到顶点 s 的简单路径
实验提示:图的存储可采用邻接矩阵或邻接表;
5.2.2 源码
//最大顶点数
//用于广度优先遍历的队列的初始分配量
typedef int Status;
typedef char VertexType[10];
typedef int EdgeType;
typedef int Boolean;
typedef struct
{
VertexType vexs[MAXVEX];//顶点表
EdgeType arc[MAXVEX][MAXVEX];//邻接矩阵
int numVertexs,numEdges;//图中的顶点数和边数
int kind;//图的种类
}MGraph;
typedef struct//顺序存贮结构的队列
{
int data[MAXSIZE];
int front;
int rear;
}Queue;
Status InitQueue(Queue &Q)
{
Q.front = 0;
Q.rear = 0;
return OK;
}
Status EnQueue(Queue &Q,int e)
{
if((Q.rear+1)%MAXSIZE == Q.front)//队满的标志
return ERROR;
Q.data[Q.rear] = e;
Q.rear = (Q.rear+1)%MAXSIZE;//队尾指针后移一位
return OK;
}
Status DeQueue(Queue &Q,int &e)
{
if(Q.front == Q.rear)//队空
return ERROR;
e = Q.data[Q.front];
Q.front = (Q.front+1)%MAXSIZE;//队头指针后移
return OK;
}
Status QueueEmpty(Queue &Q)
{
if(Q.front == Q.rear)
return TRUE;
else
return FALSE;
}
void CreateMGraph(MGraph &G)
{
int i,j,k,w;
printf("请输入顶点数和边数:\n");
scanf("%d%d",&(G.numVertexs),&(G.numEdges));
printf("输入图的种类:0-有向图 1-无向图 2-有向网 3-无向网\n");
scanf("%d",&(G.kind));
getchar();
for(i = 0;i < G.numVertexs;i++)//建立顶点表
{
printf("请输入第%d个顶点信息:\n",i+1);
scanf("%s",(G.vexs[i]));
}
for(i = 0;i < G.numVertexs;i++)
for(j = 0;j < G.numVertexs;j++)
if(G.kind == 0 || G.kind == 1)
G.arc[i][j] = 0;//邻接矩阵初始化
else
G.arc[i][j] = INFINITY;//邻接矩阵初始化
for(k = 0;k < G.numEdges;k++)//建立邻接矩阵
{
if(G.kind == 0 || G.kind == 1)
{
printf("请输入第%d条边(vi,vj)的下标i,下标j:\n",k+1);
scanf("%d%d",&i,&j);
w = 1;
}
else
{
printf("请输入第%d条边(vi,vj)的下标i,下标j和权值w:\n",k+1);
scanf("%d%d%d",&i,&j,&w);
}
G.arc[i-1][j-1] = w;
if(G.kind == 1 || G.kind == 3)//无向图矩阵对称
G.arc[j-1][i-1] = G.arc[i-1][j-1];
}
}
void PrintGraph(MGraph G)
{
int i,j;
for(i = 0;i < G.numVertexs;i++)//打印顶点信息
printf("第%d个顶点信息:%s\n",i+1,G.vexs[i]);
printf("邻接矩阵为:\n");
for(i = 0;i < G.numVertexs;i++)//打印邻接矩阵信息
{
for(j = 0;j < G.numVertexs;j++)
printf("%d",G.arc[i][j]);
printf("\n");
}
}
Boolean visited[MAXVEX];//访问标志数组
void DFS(MGraph G, int i)//深度优先递归算法
{
int j;
visited[i] = TRUE;
printf("%s",G.vexs[i]);//打印顶点信息
for(j = 0;j < G.numVertexs;j++)
if(G.arc[i][j] != 0&&G.arc[i][j] != INFINITY && !visited[j])
DFS(G,j);
}
void DFSTraverse(MGraph G)//深度优先遍历
{
int i;
for(i = 0;i < G.numVertexs;i++)
visited[i] = FALSE;
for(i = 0;i < G.numVertexs;i++)
if(!visited[i])
DFS(G,i);
}
void BFSTraverse(MGraph G)
{
int i,j;
Queue Q;
for(i = 0;i < G.numVertexs;i++)
visited[i] = FALSE;
InitQueue(Q);//初始化队列
for(i = 0;i < G.numVertexs;i++)
{
if(!visited[i])//若未访问过
{
visited[i] = TRUE;//设置成访问过
printf("%s",G.vexs[i]);//打印顶点信息
EnQueue(Q,i);
while(!QueueEmpty(Q))
{
DeQueue(Q,i);
for(j = 0;j < G.numVertexs;j++)
{
//判断当前顶点的邻接顶点是否访问过
if(G.arc[i][j] != 0&&G.arc[i][j] != INFINITY&&!visited[j])
{//若未访问过进行操作
visited[j] = TRUE;
printf("%s",G.vexs[j]);
EnQueue(Q,j);
}
}
}
}
}
}
Status CountDegree(MGraph G)
{
int i,j,count;
count = 0;
for(i = 0;i < G.numVertexs;i++)
{
for(j = 0;j < G.numVertexs;j++)
{
if(G.arc[i][j] != 0&&G.arc[i][j] != INFINITY)
count++;
}
printf("第%d个顶点的度为%d\n",i+1,count);
count = 0;
}
return OK;
}
Status CountOutDegree(MGraph G)
{
int i,j,count;
count = 0;
for(i = 0;i < G.numVertexs;i++)
{
for(j = 0;j < G.numVertexs;j++)
{
if(G.arc[i][j] != 0&&G.arc[i][j] != INFINITY)
count++;
}
printf("第%d个顶点的出度为%d\n",i+1,count);
count = 0;
}
return OK;
}
Status CountInDegree(MGraph G)
{
int i,j,count;
count = 0;
for(i = 0;i < G.numVertexs;i++)
{
for(j = 0;j < G.numVertexs;j++)
{
if(G.arc[j][i] != 0&&G.arc[j][i] != INFINITY)
count++;
}
printf("第%d个顶点的入度为%d\n",i+1,count);
count = 0;
}
return OK;
}
//用深度优先遍历求 V-S 简单路径
Status DFS_SimplePath(MGraph G,VertexType *PATH,int v,int s,int num)
{
int i;
visited[v] = TRUE;
strcpy(PATH[num],G.vexs[v]);
num++;
if(v == s)
{
printf("两点间的一条简单路径为:");
for(i = 0;i < num;i++)
if(strcmp(PATH[i],"\0") != 0)
printf("%s-",PATH[i]);
printf("\n");
}
else
{
for(i = 0;i < G.numVertexs;i++)
if(G.arc[v][i] != 0&&G.arc[v][i] != INFINITY&&!visited[i])
DFS_SimplePath(G,PATH,i,s,num);
}
visited[v] = FALSE;//回溯
num--;
return OK;
}
int main()
{
MGraph G;
CreateMGraph(G);
PrintGraph(G);
printf("深度遍历结果:\n");
DFSTraverse(G);
printf("\n");
printf("广度遍历结果:\n");
BFSTraverse(G);
printf("\n");
if(G.kind == 1)
CountDegree(G);
if(G.kind == 0)
{
CountOutDegree(G);
printf("\n");
CountInDegree(G);
printf("\n");
}
int i,v,s,num;
VertexType a,b;
VertexType PATH[G.numVertexs];//存放路径中顶点信息
printf("请输入要求简单路径的出发顶点的信息:\n");
scanf("%s",a);
printf("请输入要求简单路径的到达顶点的信息:\n");
scanf("%s",b);
num = 0;
for(i = 0;i < G.numVertexs;i++)
{
if(strcmp(G.vexs[i],a) == 0)
v = i;
if(strcmp(G.vexs[i],b) == 0)
s = i;
}
for(i = 0;i < G.numVertexs;i++)
visited[i] = FALSE;
for(i = 0;i < G.numVertexs;i++)
strcpy(PATH[i],"\0");
DFS_SimplePath(G,PATH,v,s,num);
return 0;
}
1.1.3 下载
链接地址: 5.2_MGRAPH1.CPP