- 实验内容
- 设计思路
- 实验代码
实验内容
- 编写一个程序,输出下面带权有向图的邻接表,并根据该邻接表,实现图的遍历运算,具体要求如下:
(1)从顶点0开始的深度优先遍历序列(递归算法)
(2)从顶点0开始的广度优先遍历序列
具体效果如下:
- 采用狄克斯特拉算法(Dijkstra),输出下面有向带权图G中从顶点0到其它各顶点的最短路径和最短路径长度。
具体效果如下:
设计思路
任务一 (一)在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#include #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; //图中顶点数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; }
//Main.cpp #include#define MAXV 100 #define MaxSize 100 #define INF 327676 #include "graph.h" //----创建图的邻接表G---------------------------------- 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 adjlist[i].firstarc=NULL; for (i=0; i =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].f irstarc; //采用头插法插入结点p G->adjlist[i].firstarc=p; } G->n=n; G->e=n; } //----输出邻接表G---------------------------------- void DispAdj(AdjGraph *G) { int i; ArcNode *p; for (i=0; i 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 n; i++) //扫描所有的单链表 { pre=G->adjlist[i].firstarc; //p指向第i个单链表的首结点 if (pre!=NULL) { p=pre->nextarc; while (p!=NULL) //释放第i个单链表的所有边结点 { 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; //p指向顶点v的第一条弧的弧头结点 while (p!=NULL) { if (visited[p->adjvex]==0) //若p->adjvex顶点未访问,递归访问它 DFS(G,p->adjvex); p=p->nextarc; //p指向顶点v的下一条弧的弧头结点 } } //----深度优先非递归算法---------------------------------- void DFS1(AdjGraph *G,int v) //非递归深度优先算法 { ArcNode *p; ArcNode *St[MAXV]; int top=-1,w,i; for (i=0; i n; i++) visited[i]=0; //顶点访问标志均置成0 printf("%3d",v); //访问顶点v visited[v]=1; top++; //将顶点v的第一个相邻顶点进栈 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); //访问w visited[w]=1; top++; //将顶点w的第一个顶点进栈 St[top]=G->adjlist[w].firstarc; break; //退出循环 } p=p->nextarc; //找下一个相邻顶点 } } } //BFS非递归算法 void BFS(AdjGraph *G,int v) { int w,i; ArcNode *p; SqQueue *qu; InitQueue(qu); int visited[MAXV]; for(i=0; i 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)
//输出从顶点v出发的所有最短路径
{
int i,j,k;
int apath[MAXV],d; //存放一条最短路径(逆向)及其顶点个数
for (i=0; i
printf(" 从顶点%d到顶点%d的路径长度为:%dt路径为:",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) //Dijkstra算法
{
int dist[MAXV],path[MAXV];
int S[MAXV]; //S[i]=1表示顶点i在S中, S[i]=0表示顶点i在U中
int Mindis,i,j,u;
for (i=0; i
dist[i]=g.edges[v][i]; //距离初始化
S[i]=0; //S[]置空
if (g.edges[v][i]
Mindis=INF; //Mindis置最大长度初值
for (j=0; j
u=j;
Mindis=dist[j];
}
S[u]=1; //顶点u加入S中
for (j=0; j
if (g.edges[u][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;
}



