实验内容
- 编写一个程序,输出下面带权有向图的邻接表,并根据该邻接表,实现图的遍历运算,具体要求如下:
(1)从顶点0开始的深度优先遍历序列(递归算法)
(2)从顶点0开始的广度优先遍历序列
![在这里插入图片描述](https://img-blog.csdnimg.cn/218f57e95ca7457ea757030eab62c440.png)
具体效果如下:
![在这里插入图片描述](https://img-blog.csdnimg.cn/c16bf85638ae485299cdd51660d6dfd2.png)
- 采用狄克斯特拉算法(Dijkstra),输出下面有向带权图G中从顶点0到其它各顶点的最短路径和最短路径长度。
![在这里插入图片描述](https://img-blog.csdnimg.cn/90e5f46e5ed2440d86566c7e2741e862.png)
具体效果如下:
![在这里插入图片描述](https://img-blog.csdnimg.cn/6167ab1f466e453f9d73d5b6e3ed1e11.png)
设计思路
任务一
(一)在graph.h中创建图的邻接表存储结构:
1.首先定义邻接表类型中的边结点类型ArcNode;
2.然后定义邻接表头结点类型VNode;
3.接着定义完整的图邻接表类型AdjGraph。
(二)在graph.h中创建队列的存储结构:
1.首先定义队列SqQueue
2.完成队列的基本算法
初始化InitQueue(SqQueue *&q)
判断是否为空QueueEmpty(SqQueue *q)
进队列enQueue(SqQueue *&q,int e)
出队列deQueue(SqQueue *&q,int &e)
(三)在main.cpp中完成图的基本运算算法:
1. 创建图的邻接表CreateAdj(AdjGraph *&G,int A[MAXV][MAXV],int n,int e);
2. 输出邻接表G DispAdj(AdjGraph G);
3. 销毁图的邻接表DestroyAdj(AdjGraph *&G);
4. 定义全局函数visited[MAXV];
5. 递归深度优先算法DFS(AdjGraph *G,int v);
6. 非递归深度优先算法DFS1(AdjGraph *G,int v);
7. 非递归广度优先算法BFS(AdjGraph *G,int v);
8.主函数 main()根据问题依次调用基本操作函数并编写通俗易懂的语句输出。
任务二
(一)在Dijkstra.h中创建图的邻接表存储结构:
1.首先定义邻接表类型中的边结点类型ArcNode;
2.然后定义邻接表头结点类型VNode;
3.接着定义完整的图邻接表类型AdjGraph。
(二)在main.cpp中完成图的基本运算算法:
1. 创建图的邻接表CreateAdj(AdjGraph *&G,int A[MAXV][MAXV],int n,int e);
2. Dijkstra算法Dijkstra(MatGraph g,int v);
3. 输出从顶点v出发的所有最短路径Dispath(MatGraph g,int dist[],int path[],int S[],int v)
实验代码
#include <iostream>
#include<bits/stdc++.h>
#define MAXV 100
#define MaxSize 100
#define INF 327676
using namespace std;
typedef char InfoType;
typedef char ElemType;
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;
typedef struct SqQueue
{
ElemType data[MaxSize];
int front,rear;
} SqQueue;
void InitQueue(SqQueue *&q)
{
q=(SqQueue *)malloc(sizeof(SqQueue));
q->front=q->rear=-1;
}
bool QueueEmpty(SqQueue *q)
{
return(q->front==q->rear);
}
bool enQueue(SqQueue *&q,int e)
{
if(q->rear==MaxSize-1)
return false;
q->rear++;
q->data[q->rear]=e;
return true;
}
bool deQueue(SqQueue *&q,int &e)
{
if(q->front==q->rear)
return false;
q->front++;
e=q->data[q->front];
return true;
}
#include <iostream>
#define MAXV 100
#define MaxSize 100
#define INF 327676
#include "graph.h"
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->adjvex=j;
p->weight=A[i][j];
p->nextarc=G->adjlist[i].f
irstarc;
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);
}
int visited[MAXV];
void DFS(AdjGraph *G,int v)
{
ArcNode *p;
visited[v]=1;
printf("%3d",v);
p=G->adjlist[v].firstarc;
while (p!=NULL)
{
if (visited[p->adjvex]==0)
DFS(G,p->adjvex);
p=p->nextarc;
}
}
void DFS1(AdjGraph *G,int v)
{
ArcNode *p;
ArcNode *St[MAXV];
int top=-1,w,i;
for (i=0; i<G->n; i++)
visited[i]=0;
printf("%3d",v);
visited[v]=1;
top++;
St[top]=G->adjlist[v].firstarc;
while (top>-1)
{
p=St[top];
top--;
while (p!=NULL)
{
w=p->adjvex;
if (visited[w]==0)
{
printf("%3d",w);
visited[w]=1;
top++;
St[top]=G->adjlist[w].firstarc;
break;
}
p=p->nextarc;
}
}
}
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("%3d",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("%3d",p->adjvex);
visited[p->adjvex]=1;
enQueue(qu,p->adjvex);
}
p=p->nextarc;
}
}
printf("\n");
}
int main()
{
AdjGraph *G;
int A[MAXV][MAXV]=
{
{0,5,INF,7,INF,INF},
{INF,0,4,INF,INF,INF},
{8,INF,0,INF,INF,9},
{INF,INF,5,0,INF,6},
{INF,INF,INF,5,0,INF},
{3,INF,INF,INF,1,0}
};
int n=6, e=10;
CreateAdj(G,A,n,e);
printf("图G的邻接表:\n");
DispAdj(G);
printf("从顶点0开始的DFS(递归算法):\n");
DFS(G,0);
printf("\n");
printf("从顶点0开始的DFS(非递归算法):\n");
DFS1(G,0);
printf("\n");
printf("从顶点0开始的BFS(非递归算法):\n");
BFS(G,0);
}
#include "Dijkstra.h"
int count=0;
void Dispath(MatGraph g,int dist[],int path[],int S[],int v)
{
int i,j,k;
int apath[MAXV],d;
for (i=0; i<g.n; i++)
if (S[i]==1 && i!=v)
{
printf(" 从顶点%d到顶点%d的路径长度为:%d\t路径为:",v,i,dist[i]);
d=0;
apath[d]=i;
k=path[i];
if (k==-1)
printf("无路径\n");
else
{
while (k!=v)
{
d++;
apath[d]=k;
k=path[k];
}
d++;
apath[d]=v;
printf("%d",apath[d]);
for (j=d-1; j>=0; j--)
printf(",%d",apath[j]);
printf("\n");
}
}
}
void Dijkstra(MatGraph g,int v)
{
int dist[MAXV],path[MAXV];
int S[MAXV];
int Mindis,i,j,u;
for (i=0; i<g.n; i++)
{
dist[i]=g.edges[v][i];
S[i]=0;
if (g.edges[v][i]<INF)
path[i]=v;
else
path[i]=-1;
}
S[v]=1;
path[v]=0;
for (i=0; i<g.n-1; i++)
{
Mindis=INF;
for (j=0; j<g.n; j++)
if (S[j]==0 && dist[j]<Mindis)
{
u=j;
Mindis=dist[j];
}
S[u]=1;
for (j=0; j<g.n; j++)
if (S[j]==0)
{
if (g.edges[u][j]<INF&&dist[u]+g.edges[u][j]<dist[j])
{
dist[j]=dist[u]+g.edges[u][j];
path[j]=u;
}
}
}
Dispath(g,dist,path,S,v);
}
int main()
{
MatGraph g;
int A[MAXV][MAXV]=
{
{0,5,INF,7,INF,INF},
{INF,0,4,INF,INF,INF},
{8,INF,0,INF,INF,9},
{INF,INF,5,0,INF,6},
{INF,INF,INF,5,0,INF},
{3,INF,INF,INF,1,0}
};
int n=6, e=8;
CreateMat(g,A,n,e);
printf("图G的邻接矩阵:\n");
DispMat(g);
int v=0;
printf("从%d顶点出发的最短路径求解过程如下:\n",v);
Dijkstra(g,v);
return 1;
}