最短路径问题
在《图的存储与遍历》的基础上,实现求最短路径的Dijstra算法,并将该算法用于求下图从顶点A到其它各顶点的最短路径,以验证算法的正确性。
#include
#include
#include
#define MaxVertexNum 20 //最大定点数设为100
#define MAXSIZE 20
#define INF 999 //定义无穷大
/****************图的邻接矩阵定义 *******************/
typedef char VertexType; //定点类型设为字符型
typedef int EdgeType; //边的权值设为字符型
typedef struct
{
VertexType vexs[MaxVertexNum]; //顶点表
EdgeType edges[MaxVertexNum][MaxVertexNum]; //邻接矩阵,即边表
int n; //n为顶点数
int e; //e为边数
}MGraph;
/****************图的邻接表定义 *******************/
typedef struct node //边表结点
{
int adjvex; //邻接点域
EdgeType info; //数据域
struct node *next; //指向下一个邻接点的指针域
} EdgeNode;
typedef struct vnode //顶点表结点
{
VertexType vertex; //顶点域
EdgeNode *firstedge; //边表头指针
}VertexNode;
typedef struct
{
VertexNode AdjList[MaxVertexNum]; //顶点表
int n; //顶点表顶点数
int e; //顶点表边数
}ALGraph;
/****************队列的类型及各种操作 *******************/
typedef int datatype;
typedef struct Queue
{
datatype data[MAXSIZE];
datatype top;
datatype bottom;
}Queue;
//初始化
void InitQueue(Queue * p)
{
p->top = 0;
p->bottom = 0;
}
//入队
void EnQueue(Queue *p,datatype val)
{
p->data[p->bottom] = val;
(p->bottom)++;
p->bottom = (p->bottom) % MAXSIZE;
}
//出队
datatype DeQueue(Queue *p)
{
datatype p1;
p1 = p->top;
(p->top)++;
p->top = ((p->top) + MAXSIZE) % MAXSIZE;
return p->data[p1];
}
//队列为空
int QueueEmpty(Queue *p)
{
if(p->top == p->bottom)
{
return -1;
}
}
/****************图的创建与打印 *******************/
//创建邻接矩阵
void CreateMGraph(MGraph *G)
{
int i,j,k,w,weight;
char ch;
printf("请输入顶点数和边数(输入格式为:顶点数,边数):\n");
scanf("%d,%d",&(G->n),&(G->e));
printf("请输入顶点信息:\n");
for(i = 0; i < G->n; i++)
{
getchar();
scanf("%c",&(G->vexs[i]));
}
for(i = 0; i < G->n; i++)
{
for(j = 0; j < G->n; j++)
{
if(i == j)
{
G->edges[i][j] = 0;
}
else
{
G->edges[i][j] = INF;
}
}
}
printf("请输入每条边对应的两个顶点的序号和权值(输入格式为:i,j,权值):\n");
for(k = 0; k < G->e; k++)
{
scanf("%d,%d,%d",&i,&j,&weight);
G->edges[i][j] = weight;
}
}
//打印邻接矩阵
void printMGraph(MGraph *G)
{
int i,j;
printf("邻接矩阵为:\n");
for(i = 0; i < G->n; i++)
{
printf("V%-4c ",G->vexs[i]);
for(j = 0; j < G->n; j++)
{
if(G->edges[i][j] == INF)
printf("∞ ");
else
printf("%-4d ",G->edges[i][j]);
}
printf("\n");
}
}
//创建邻接表
void MGraphtoALGraph(MGraph *mG,ALGraph *alG)
{
int i,j,k;
EdgeNode * s;
alG->n = mG->n;
alG->e = mG->e;
for(i = 0; i < alG->n; i++)
{
alG->AdjList[i].vertex = mG->vexs[i];
alG->AdjList[i].firstedge = NULL;
}
for(i = 0; i < mG->n; i++)
{
for(j = 0; j < mG->n; j++)
{
if(mG->edges[i][j] != 0 && mG->edges[i][j] != INF)
{
s = (EdgeNode *)malloc(sizeof(EdgeNode));
s->adjvex = j;
s->next = alG->AdjList[i].firstedge;
s->info = mG->edges[i][j];
alG->AdjList[i].firstedge = s;
}
}
}
}
//打印邻接表
void printALGraph(ALGraph *alG)
{
int i,j,k;
EdgeNode *p;
printf("邻接表为:\n");
for(i = 0; i < alG->n; i++)
{
printf("V%c",alG->AdjList[i].vertex);
p = alG->AdjList[i].firstedge;
while(p != NULL)
{
printf("->%d,%d",p->adjvex,p->info);
p = p->next;
}
printf("\n");
}
}
/****************图的深度优先遍历 *******************/
int visited[MaxVertexNum];
//对邻接矩阵存储的图点进行DFS搜索
void DFST(MGraph *mG, int i)
{
if(visited[i] == 0)
{
int j;
printf("visit vertex: %c\n",mG->vexs[i]);
visited[i] = 1;
for(j = 0; j < mG->n; j++)
{
if(mG->edges[i][j] != 0 && mG->edges[i][j] != INF)
{
j;
DFST(mG, j);
}
}
}
}
//对邻接矩阵存储的图点进行DFS搜索
void DFSTraverse1(MGraph *mG)
{
int i,j,k;
memset(visited, 0, sizeof(mG->n));
for(i = 0; i < mG->n; i++)
{
if(visited[i] == 0)
{
DFST(mG, i);
}
}
}
//对邻接表存储的图进行DFS搜索
void DFSAL(ALGraph *alG, int i)
{
EdgeNode * p;
printf("visit vertex: %c\n",alG->AdjList[i].vertex);
visited[i] = 1;
p = alG->AdjList[i].firstedge;
while(p != NULL)
{
if(visited[p->adjvex] == 0)
{
DFSAL(alG,p->adjvex);
}
p = p->next;
}
}
//对邻接表存储的图进行DFS搜索
void DFSTraverse2(ALGraph *alG)
{
int i;
for(i = 0; i < alG->n; i++)
{
visited[i] = 0;
}
for(i = 0; i < alG->n; i++)
{
if(visited[i] == 0)
{
DFSAL(alG,i);
}
}
}
/****************图的广度优先遍历 *******************/
//对邻接矩阵存储的图进行BFS搜索
void BFSM(MGraph *mG,int k)
{
int i,j;
Queue Q;
InitQueue(&Q);
printf("visit vertex: %c\n",mG->vexs[k]);
visited[k] = 1;
EnQueue(&Q,k);
while(QueueEmpty(&Q) != -1)
{
i = DeQueue(&Q);
for(j = 0; j < mG->n; j++)
{
if(mG->edges[i][j] != 0 && mG->edges[i][j] != INF && visited[j] == 0)
{
printf("visit vertex: %c\n",mG->vexs[j]);
visited[j] = 1;
EnQueue(&Q,j);
}
}
}
}
//对邻接矩阵存储的图进行BFS搜索
void BFSTraverse1(MGraph *mG)
{
int i;
for(i = 0; i < mG->n; i++)
{
visited[i] = 0;
}
for(i = 0; i < mG->n; i++)
{
if(visited[i] == 0)
{
BFSM(mG,i);
}
}
}
//对邻接表存储的图进行BFS搜索
void BFSAL(ALGraph *alG, int k)
{
int i, j;
Queue Q; //队列
InitQueue(&Q);
EdgeNode *p;
printf("visit vertex: %c\n",alG->AdjList[k].vertex);
visited[k] = 1;
EnQueue(&Q,k);
while(QueueEmpty(&Q) != -1)
{
i = DeQueue(&Q);
p = alG->AdjList[i].firstedge;
while(p != NULL && visited[i] == 0)
{
i = p->adjvex;
printf("visit vertex: %c\n",alG->AdjList[i].vertex);
visited[i] = 1;
EnQueue(&Q,i);
p = p->next;
}
}
}
//对邻接表存储的图进行BFS搜索
void BFSTraverse2(ALGraph *alG)
{
int i;
for(i = 0; i < alG->n; i++)
{
visited[i] = 0;
}
for(i = 0; i < alG->n; i++)
{
if(visited[i] == 0)
{
BFSAL(alG,i);
}
}
}
/****************************************Dijkstra函数*********************************/
void dijkstra(MGraph * mG)
{
int i,j,k,l,min,v;
int d[MAXSIZE];
bool vis[MAXSIZE];
for(i = 0; i < mG->n; i++)
{
vis[i] = 0;
d[i] = mG->edges[0][i];
}
d[0] = 0;
vis[0] = 1;
for(i = 1; i < mG->n; i++)
{
min = INF;
v = -1;
for(j = 0; j < mG->n; j++)
{
if(vis[j] == 0 && d[j] < min)
{
v = j;
min = d[j];
}
}
vis[v] = 1;
for(k = 0; k < mG->n; k++)
{
if(vis[k] == 0 && d[k] > mG->edges[v][k] + min)
{
d[k] = mG->edges[v][k] + min;
}
}
}
for(i = 0; i < mG->n; i++)
{
printf("%d------%c->%c\n",d[i],mG->vexs[0],mG->vexs[i]);
}
}
/****************************************main函数*************************************/
int main()
{
MGraph G;
ALGraph alG;
CreateMGraph(&G);
printMGraph(&G);
MGraphtoALGraph(&G,&alG);
printALGraph(&alG);
printf("对邻接矩阵存储的图点进行DFS搜索:\n");
DFSTraverse1(&G);
printf("对邻接表存储的图进行DFS搜索:\n");
DFSTraverse2(&alG);
printf("对邻接矩阵存储的图进行BFS搜索:\n");
BFSTraverse1(&G);
printf("对邻接表存储的图进行BFS搜索:\n");
BFSTraverse2(&alG);
dijkstra(&G);
}