#include<stdio.h>
#include<stdlib.h>
#define MaxVertexNum 100
#define N 100
typedef char VertexType;
typedef int EdgeType;
int visited[N];
typedef struct
{
VertexType vexs[MaxVertexNum];
EdgeType edges[MaxVertexNum][MaxVertexNum];
int n,e;
}MGraph;//邻接矩阵
//邻接表
typedef struct node /*表结点*/
{
int adjvex; /*邻接点域*/
struct node * next; /*指向下一个邻接点的指针域*/
/* int info; 若要表示边上信息,则应增加一个数据域info*/
}EdgeNode;
typedef struct vnode /*表头结点*/
{
VertexType vertex; /*顶点域*/
EdgeNode * firstedge; /*边表头指针*/
}VertexNode;
typedef struct
{
VertexNode adjlist[MaxVertexNum]; /*邻接表*/
int n,e; /*顶点数和边数*/
}ALGraph; /*ALGraph是以邻接表方式存储的图类型*/
typedef struct QNode
{
int data;//存放数据元素信息
struct QNode *next;//
}QNode;
typedef struct LQueue
{
QNode *front;//队头指针
QNode *rear;//队尾指针
}CirQueue;
QNode *head;
int InitQueue(CirQueue *Q)
{
Q=(CirQueue*)malloc(sizeof(CirQueue));// 为链对头尾指针申请空间
QNode *head=(QNode*)malloc(sizeof(QNode));//链队头结点
head->next=NULL;
Q->front=head;
Q->rear=head;
}
int EnQueue(CirQueue *Q,int n)//入队
{
QNode *node;
node=(QNode*)malloc(sizeof(QNode));
if(node==NULL)
{
printf("error\n");
return 0;
}
node->data=n;
node->next=NULL;
Q->rear->next=node;
Q->rear=node;
return 1;
}
int QueueEmpty(CirQueue *Q)//判空
{
if(Q->front==Q->rear)
{
return 1;//空返回1
}
else
{
return 0;//非空返回0
}
}
int DeQueue(CirQueue *Q)//出队 并删除
{
int m;
QNode *node;
if(Q->front==Q->rear)
{
printf("error\n");
return 0;
}
else
{
node=Q->front->next;
m=node->data;
printf("队头元素:%d 已经删除成功\n",m);
Q->front->next=node->next;
if(node==Q->rear)
{
Q->rear=Q->front;
}
free(node);
return 1;
}
}
void CreateMGraph(MGraph *G)//有向图邻接矩阵储存法
{
int i, j, k;
printf("请输入顶点数和边数(输入格式为:顶点数,边数):\n");
scanf("%d %d",&G->n,&G->e); /*输入顶点数和边数*/
printf("请输入顶点信息(输入格式为: <回车>顶点号):\n");
for (i=0;i<G->n;i++)
scanf("\n%c", &(G->vexs[i])); /*输入顶点信息,建立顶点表*/
for (i=0;i<G->n;i++)
for (j=0;j<G->n;j++)
G->edges[i][j]=0; /*初始化邻接矩阵*/
printf("请输入每条边对应的两个顶点的序号(输入格式为:i,j):\n");
for (k=0;k<G->e;k++)
{
scanf("%d,%d",&i,&j); /*输入e条边,建立邻接矩阵*/
G->edges[i][j]=1;
/*若此处加入G->edges[j][i]=1;,则为无向图的邻接矩阵存储建立*/
}
}
void CreateALGraph(ALGraph *G)//邻接表储存
{
int i,j,k;
EdgeNode *s;
printf("请输入顶点数和边数(输入格式为:顶点数,边数):\n");
scanf("%d %d",&(G->n),&(G->e)); /*读入顶点数和边数*/
printf("\n请输入顶点信息(输入格式为: <回车>顶点号):\n");
for (i = 0; i < G->n; i++) /*建立有n个顶点的顶点表*/
{
scanf("\n%c",&(G->adjlist[i].vertex)); /*读入顶点信息*/
G->adjlist[i].firstedge = NULL; /*顶点的边表头指针设为空*/
}
printf("\n请输入边的信息(输入格式为:i j):\n");
for (k=0; k<G->e; k++) /*建立边表*/
{
scanf("%d %d", &i, &j); /*读入边<Vi,Vj>的顶点对应序号*/
s = (EdgeNode*)malloc(sizeof(EdgeNode));
/*生成新边表结点s*/
s->adjvex = j; /*邻接点序号为j*/
s->next = G->adjlist[i].firstedge;
/*将新边表结点s用头插法插入到顶点Vi 的边表头部*/
G->adjlist[i].firstedge = s;
}
}
/*DFS*/ //以邻接表为储存方式的深度优先搜索方式 2
void DFSAL(ALGraph *G, int i) /*BFS*/
{
EdgeNode *p;
printf("visit vertex:V%c\n", G->adjlist[i].vertex); /*访问顶点vi*/
visited[i]=1; /*标记vi已访问*/
p=G->adjlist[i].firstedge; /*取vi边表的头指针*/
while(p) /*依次搜索vi的邻接点vj */
{
if (!visited[p->adjvex])
/*若vj尚未访问,则以vj为出发点向纵深搜索*/
DFSAL(G,p->adjvex);
p=p->next; /*找vi的下一个邻接点*/
}
}
void DFSTraverseAL(ALGraph *G)
{
int i;
for (i=0; i<G->n; i++)
visited[i]=0; /*标志向量初始化*/
for (i=0; i<G->n; i++) /*vi未访问过,从vi开始DFS搜索*/
if (!visited[i])
DFSAL(G,i);
}
//以邻接矩阵为储存方式的广度优先搜索 1
void BFSM(MGraph *G,int k)
{
int i, j;
CirQueue *Q;
InitQueue(Q);
printf("visit vertex:V%c\n",G->vexs[k]); /*访问原点vk*/
visited[k] =1;
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]) /*若vj未访问*/
{
printf("visit vertex:V%c\n", G->vexs[j]); /*访问vj */
visited[j] =1;
EnQueue(Q,j); /*访问过的vj入队列*/
}
}
}
void BFSTraverseAL(MGraph *G)
{ int i;
for (i=0; i<G->n; i++)
visited[i] =0; /*标志向量初始化*/
for (i=0; i<G->n; i++)
if (!visited[i]) /* vi未访问过,从vi开始BFS搜索*/
BFSM(G,i);
}
int main()
{
int HAO;
printf("有两种选择方式:\n");
printf("1:以邻接矩阵为储存方式的广度优先搜索\n");
printf("2:
\n");
printf("请选择:\n");
scanf("%d",&HAO);
if(HAO==1)
{
MGraph G;
CreateMGraph(&G);
BFSTraverseAL(&G);
}
else
{
ALGraph G;
CreateALGraph(&G);
DFSTraverseAL(&G);
}
}
这个实验是结合书上两种储存方式和两种搜索方式进行的结合,图的应用十分广泛,但考试时只出一些原理,编程的估计只是很少。。
实验七(以邻接矩阵为储存方式的广度优先搜索和以邻接表为储存方式的深度优先搜索方式)
最新推荐文章于 2022-01-23 14:40:25 发布