实验07 图的存储与遍历

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验7图的存储与遍历
一、实验目的
掌握图这种复杂的非线性结构的邻接矩阵和邻接表的存储表示,以及在此两种常用存储方式下深度优先遍历(dfs)和广度优先遍历(BFS)操作的实现。

二、实验内容
内容1对以邻接矩阵为存储结构的图进行DFS和BFS遍历
(1) 问题描述:以邻接矩阵为图的存储结构,实现图的DFS和BFS遍历。

(2) 基本要求:建立一个图的邻接矩阵表示,输出顶点的一种DFS和BFS序列。

(3) 测试数据:如图下图所示。

(4) 实现提示:图的DFS遍历可通过递归调用或用栈来实现。

其思想是:只要当前结点未访问过,就访问该结点,沿着其一条分支深入下去,每深入一个未访问过的结点,就访问这个结点,然后从这个结点继续进行DFS遍历。

在这一过程中,若深入时遇到一个已访问过的结点,则查找是否有与这个结点相邻的下一个未访问过的结点。

若有则继续深人,否则将退回到这个结点的前一个结点,再找下一个相邻的本访问过的结点,……如此进行下去,直到所有的结点都被访问过。

BFS遍历可利用队列来帮助实现,也可以用栈。

实现方法与二叉树的层次遍历类似。

题目2对以邻接表为存储结构的图进行DFS和BFS遍历
(1) 问题描述:以邻接表为存储结构,实现图的DFS和BFS遍历。

(2) 基本要求:建立一个图的邻接表存储,输出顶点的一种DFS和BFS序列。

(3) 测试数据:如下图所示:
(4) 实现提示:以邻接表为存储结构的图的DFS和BFS算法的实现思想与以
邻接矩阵为存储结构的实现是一样的。

只是由于图的存储形式不同。

而具体到取第一个邻接点和下一个邻接点的语句表示上有所差别而已。

三、实验步骤
1. 明确图的ADT定义;
2. 在不同存储结构下定义顶点节点、边节点、图,以及创建、求邻接点、遍历等基本操作的实现;
3. 利用图的基本操作创建图;
4. 通过测试数据检验;
5. 提交实验报告。

四、实现提示
部分代码
#define MaxVertexNum 10 //设最大顶点数为10
#include <stdio.h>
#include <stdlib.h>
typedef char VertexType;
typedef int EdgeType;
typedef struct{
char vexs[10];
int edges[10][10];
int n,e;
}MGraph;
#define FALSE 0
#define TRUE 1
#define Error printf
int visited[10];
void CreateMGraph(MGraph *G);
void DFSTraverseM(MGraph *G);
void BFSTraverseM(MGraph *G);
void DFSM(MGraph *G,int i);
void BFSM(MGraph *G,int i);
#define QueueSize 30 /*假定预分配的队列空间最多为30*/ typedef int DataType; /*队列中的元素类型为字符型*/ typedef struct{
int front; /*队头指针,队非空时指向队头元素*/
int rear; /*队尾指针,队非空时指向队尾元素的下一位置*/ int count; /*计数器,记录队中元素总数*/
DataType data[QueueSize];
}CirQueue;
void InitQueue(CirQueue *Q) /*初始队列*/
{Q->front=Q->rear=0;
Q->count=0;
}
int QueueEmpty(CirQueue *Q) /*判队空*/
{return Q->count==0;
}
int QueueFull(CirQueue *Q) /*判队满*/
{return Q->count==QueueSize;
}
void EnQueue(CirQueue *Q,DataType x) /*入队*/
{if (QueueFull(Q))
Error("Queue overflow"); /*队满上溢*/
else {Q->count++; /*队列元素个数加1*/
Q->data[Q->rear]=x; /*新元素插入队列*/
Q->rear=(Q->rear+1)%QueueSize; /*循环队列的尾指针加1*/ }
}
DataType DeQueue(CirQueue *Q) /*出队*/
{DataType temp;
if (QueueEmpty(Q))
Error("Queue underflow"); /*队空下溢*/
else {temp=Q->data[Q->front];
Q->count--; /*队列元素个数减1*/
Q->front=(Q->front+1)%QueueSize; /*循环队列的头指针加1*/ return temp;
}
}
main()
{MGraph *G; /*定义一个以邻接矩阵为存储类型的图G*/
char ch1,ch2;
G= (MGraph *)malloc(sizeof(MGraph));
printf("create graph(adjoining matrix ):\n"); /*创建图G的存储*/ CreateMGraph(G);
printf("create graph success 。

\n");
ch1='y';
while(ch1=='y' || ch1=='Y')
{printf("select:\n");
printf("\nb<CR>----------------Degree First search ");
printf("\nc<CR>----------------breadth First search ");
printf("\nd<CR>------------------exit\n");
scanf("\n%c",&ch2);
switch (ch2)
{case 'B':
case 'b':DFSTraverseM(G);break;
case 'C':
case 'c':BFSTraverseM(G);break;
case 'D':
case 'd':ch1='n';break;
default:ch1='n';
}
}
}
void CreateMGraph(MGraph *G)
{/*建立有向图G的邻接矩阵存储*/
int i,j,k,w;
char ch;
printf("input vertex number and edge number(input
format:vn,en):\n");/*输入顶点数和边数,输入格式:顶点数,边数*/
scanf("%d,%d",&(G->n),&(G->e));
printf("input vertex(input format:serial number<CR>):\n");/*输入顶点信息,建立顶点表,输入格式为:顶点号<CR>)/*/
for (i=0;i<G->n;i++)
scanf("\n%c",&(G->vexs[i]));
printf("input edge(format:i,j<CR>):\n");/*输入e条边,输入格式为:i,j*/
for (k=0;k<G->e;k++)
{scanf("\n%d,%d",&i,&j); /*输入e条边,建立邻接矩阵*/
G->edges[i][j]=1;
}
}/*CreateMGraph*/
void DFSTraverseM(MGraph *G)
{ /*深度优先遍历以邻接矩阵存储的图G*/
int i;
printf("Degree First search\n");
for(i=0;i<G->n;i++)
visited[i]=FALSE;
for(i=0;i<G->n;i++)
if(!visited[i])DFSM(G,i);
} /*DFSTraverse*/
void DFSM(MGraph *G,int i)
{/*以Vi为出发点,对邻接矩阵存储的图G进行DFS搜索*/ int j;
printf(" edge:v%c\n",G->vexs[i]);
visited[i]=TRUE;
for(j=0;j<G->n;j++)
if(G->edges[i][j]==1&&!visited[j])
DFSM(G,j);
} /*DFSM*/
void BFSTraverseM(MGraph *G)
{/*广度优先遍历邻接矩阵存储的图G*/
int i;
printf("breadth First search\n");
for (i=0;i<G->n;i++)
visited[i]=FALSE; /*标志向量初始化*/
for (i=0;i<G->n;i++)
if (!visited[i]) BFSM(G,i);/*Vi未访问过,以Vi为原点开始BFS搜索*/ }/*BFSTraverseM*/
void BFSM(MGraph *G,int k)
{/*以Vi为出发点,对邻接矩阵存储的图G进行BFS搜索*/
int i,j;
CirQueue Q;
InitQueue(&Q);
printf("vertex:v%c\n",G->vexs[k]);
visited[k]=TRUE;
EnQueue(&Q,k); /*原点Vk入队列*/
while (!QueueEmpty(&Q))
{i=DeQueue(&Q); /*Vi出队列*/
for (j=0;j<G->n;j++) /*依次搜索Vi的邻接点Vj*/
if (G->edges[i][j]==1 && !visited[j])
{printf("vertex:v%c\n",G->vexs[j]);
visited[j]=TRUE;
EnQueue(&Q,j); /*访问过的Vj入队列*/
}
}
}/*BFSM*/
五、思考与提高
如果存储结构采用十字链表或者邻接多重表,该做如何修改!。

相关文档
最新文档