一、实验目的
1.掌握邻接矩阵、领接表的运算。
2.编写程序,实现深度优先搜索和广度搜索算法。
二、实验环境
windows 10、Visual C++6.0
三、实验内容
1.图的深度优先
#include "graph.cpp"
int visited[MAXV]={0};
void DFS(AdjGraph *G,int v)
{
ArcNode *p;
visited[v]=1;
printf("%d ",v);
p=G->adjlist[v].firstarc;
while (p!=NULL)
{
if (visited[p->adjvex]==0)
DFS(G,p->adjvex);
p=p->nextarc;
}
}
int main()
{
AdjGraph *G;
int A[MAXV][MAXV]={{0,0,1,1,0,1,1},
{0,0,1,1,1,1,0},
{1,1,0,0,0,1,1},
{1,1,0,0,1,0,1},
{0,1,0,1,0,1,1},
{1,1,1,0,1,0,0},
{1,0,1,1,1,0,0}};
int n=7, e=14;
CreateAdj(G,A,n,e);
printf("图G的邻接表:\n");
DispAdj(G); //输出邻接表G
printf("深度优先序列(递归):");DFS(G,2);printf("\n");
DestroyAdj(G);
return 1;
}
//----------------------------------深度主函数
2.图的广度优先
#include "graph.cpp"
#define MaxSize 100
typedef int ElemType;
typedef struct
{
ElemType data[MaxSize];
int front,rear;
} SqQueue;
void InitQueue(SqQueue *&q)
{ q=(SqQueue *)malloc (sizeof(SqQueue));
q->front=q->rear=0;
}
void DestroyQueue(SqQueue *&q)
{
free(q);
}
bool QueueEmpty(SqQueue *q)
{
return(q->front==q->rear);
}
bool enQueue(SqQueue *&q,ElemType e)
{ if ((q->rear+1)%MaxSize==q->front)
return false;
q->rear=(q->rear+1)%MaxSize;
q->data[q->rear]=e;
return true;
}
bool deQueue(SqQueue *&q,ElemType &e)
{ if (q->front==q->rear)
return false;
q->front=(q->front+1)%MaxSize;
e=q->data[q->front];
return true;
}
void BFS(AdjGraph *G,int v)
{
int w,i;
ArcNode *p;
SqQueue *qu;
InitQueue(qu);
int visited[MAXV];
for (i=0;i<G->n;i++) visited[i]=0;
printf("%2d",v);
visited[v]=1;
enQueue(qu,v);
while (!QueueEmpty(qu))
{
deQueue(qu,w);
p=G->adjlist[w].firstarc;
while (p!=NULL)
{
if (visited[p->adjvex]==0)
{
printf("%2d",p->adjvex);
visited[p->adjvex]=1; //置已访问标记
enQueue(qu,p->adjvex);
}
p=p->nextarc;
}
}
printf("\n");
}
int main()
{
AdjGraph *G;
int A[MAXV][MAXV]={{0,1,0,1,1},{1,0,1,1,1},
{0,1,0,1,1},{1,0,1,0,1},{1,0,1,0,0}};
int n=5, e=8;
CreateAdj(G,A,n,e);
printf("图G的邻接表:\n");
DispAdj(G);
printf("广度优先序列:");BFS(G,2);printf("\n");
DestroyAdj(G);
return 1;
}
//----------------------------------广度主函数
#include <stdio.h>
#include <malloc.h>
#include "graph.h"
void CreateMat(MatGraph &g,int A[MAXV][MAXV],int n,int e)
{
int i,j;
g.n=n; g.e=e;
for (i=0;i<g.n;i++)
for (j=0;j<g.n;j++)
g.edges[i][j]=A[i][j];
}
void DispMat(MatGraph g)
{
int i,j;
for (i=0;i<g.n;i++)
{
for (j=0;j<g.n;j++)
if (g.edges[i][j]!=INF)
printf("%4d",g.edges[i][j]);
else
printf("%4s","∞");
printf("\n");
}
}
void CreateAdj(AdjGraph *&G,int A[MAXV][MAXV],int n,int e)
{ int i,j;
ArcNode *p;
G=(AdjGraph *)malloc(sizeof(AdjGraph));
for (i=0;i<n;i++) G->adjlist[i].firstarc=NULL;
for (i=0;i<n;i++)
for (j=n-1;j>=0;j--)
if (A[i][j]!=0 && A[i][j]!=INF) { p=(ArcNode *)malloc(sizeof(ArcNode)); p
p->adjvex=j;
p->weight=A[i][j];
p->nextarc=G->adjlist[i].firstarc; G->adjlist[i].firstarc=p;
}
G->n=n; G->e=n;
}
void DispAdj(AdjGraph *G)
{ int i;
ArcNode *p;
for (i=0;i<G->n;i++)
{
p=G->adjlist[i].firstarc;
printf("%3d: ",i);
while (p!=NULL)
{
printf("%3d[%d]→",p->adjvex,p->weight);
p=p->nextarc;
}
printf("∧\n");
}
}
void DestroyAdj(AdjGraph *&G) //销毁图的邻接表
{ int i;
ArcNode *pre,*p;
for (i=0;i<G->n;i++)
{ pre=G->adjlist[i].firstarc;
if (pre!=NULL)
{ p=pre->nextarc;
while (p!=NULL)
{ free(pre);
pre=p; p=p->nextarc;
}
free(pre);
}
}
free(G);
}
//----------------------------------graph.cpp
#define INF 32767
#define MAXV 100
typedef char InfoType;
typedef struct
{ int no;
InfoType info;
} VertexType;
typedef struct
{ int edges[MAXV][MAXV];
int n,e;
VertexType vexs[MAXV];
} MatGraph;
typedef struct ANode
{ int adjvex;
struct ANode *nextarc;
int weight;
} ArcNode;
typedef struct Vnode
{ InfoType info;
int count;
ArcNode *firstarc;
} VNode;
typedef struct
{ VNode adjlist[MAXV];
int n,e;
} AdjGraph;
//----------------------------------头文件
四、实验结果与分析
分析:
深度优先搜索:假设初始状态时图中所有顶点未曾访问,则深度优先搜索可从图中某个顶点v出发,访问此顶点,然后依次从v的未被访问的邻接点出发深度优先遍历图,直至图中所有与v有路径相通的顶点都被访问到;若此时图中尚有顶点未被访问,则另选图中一个未曾访问的顶点作起始点,重复上述过程,直至图中所有顶点都被访问到为止。
广度优先搜索是一种图的搜索算法。在搜索开始,会确定一个搜索的起点,然后选择一个与其相邻的且在值上与节点最接近的点,然后迭代进行,如果在最后发现所有邻居都已经被访问过,则开始回溯。