-
Notifications
You must be signed in to change notification settings - Fork 46
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
求图最短路径 #144
base: master
Are you sure you want to change the base?
求图最短路径 #144
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,318 @@ | ||
// | ||
// main.c | ||
// homework7 | ||
// | ||
// Created by Huhongbo on 2017/5/17. | ||
// Copyright © 2017年 Huhongbo. All rights reserved. | ||
// | ||
|
||
#include <stdio.h> | ||
#include <stdlib.h> | ||
|
||
typedef enum | ||
{ | ||
OK, | ||
ERROR, | ||
OVERFLOW | ||
}Status; | ||
|
||
typedef enum | ||
{ | ||
true, | ||
false | ||
}bool; | ||
|
||
|
||
//图的数组存储结构 | ||
#define MAX_VERTEX_NUM 10 | ||
#define VRType int | ||
#define InfoType int | ||
#define VertexType int | ||
#define INFINITY -1 | ||
|
||
typedef struct ArcCell | ||
{ | ||
VRType adj; | ||
InfoType *info; | ||
}ArcCell, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; | ||
|
||
typedef struct | ||
{ | ||
VertexType vexs[MAX_VERTEX_NUM]; | ||
AdjMatrix arcs; | ||
int vexnum, arcnum; //图的顶点数和弧数; | ||
}MGraph; | ||
|
||
|
||
//队列的双链存储结构 | ||
#define QElemType int | ||
|
||
typedef struct QNode | ||
{ | ||
QElemType data; | ||
struct QNode *next; | ||
struct QNode *pre; | ||
}QNode, *QueuePtr; | ||
|
||
typedef struct LinkQueue | ||
{ | ||
QueuePtr front; | ||
QueuePtr rear; | ||
}LinkQueue; | ||
|
||
//队列的基本操作 | ||
Status InitQueue(LinkQueue *Q); | ||
Status EnQueue(LinkQueue*Q, QElemType e); | ||
Status DeQueue(LinkQueue*Q, QElemType*e); | ||
bool QueueEmpty(LinkQueue*Q); | ||
Status DestroyQueue(LinkQueue*Q); | ||
|
||
//图的基本操作 | ||
Status LocateVex(MGraph *G, int v1, int v2); | ||
Status CreateUDN(MGraph *G); | ||
int FirstAdjVex(MGraph *G, int u); | ||
int NextAdjvex(MGraph *G, int u, int w); | ||
Status BFSTraverse(MGraph*G, LinkQueue *Q, int a, int b); | ||
Status print(LinkQueue *Q, int a); | ||
|
||
//队列的基本操作 | ||
Status InitQueue(LinkQueue *Q) | ||
{ | ||
Q->front = Q->rear = (QueuePtr)malloc(sizeof(QNode)); | ||
if (!Q->front) | ||
{ | ||
return ERROR; | ||
} | ||
Q->front->next = Q->rear->next = NULL; | ||
return OK; | ||
} | ||
|
||
Status EnQueue(LinkQueue*Q, QElemType e) | ||
{ | ||
QueuePtr p = (QueuePtr)malloc(sizeof(QNode)); | ||
if (!p) | ||
{ | ||
return ERROR; | ||
} | ||
else | ||
{ | ||
p->data = e; | ||
p->next = NULL; | ||
p->pre = Q->front; | ||
Q->rear->next = p; | ||
Q->rear = p; | ||
return OK; | ||
} | ||
} | ||
|
||
Status DeQueue(LinkQueue*Q, QElemType*e) | ||
{ | ||
if (Q->front == Q->rear) | ||
{ | ||
return ERROR; | ||
} | ||
Q->front = Q->front->next; | ||
*e = Q->front->data; | ||
return OK; | ||
} | ||
|
||
bool QueueEmpty(LinkQueue*Q) | ||
{ | ||
if (Q->front == Q->rear) | ||
{ | ||
return true; | ||
} | ||
else | ||
{ | ||
return false; | ||
} | ||
} | ||
|
||
Status DestroyQueue(LinkQueue*Q) | ||
{ | ||
while (Q->front) | ||
{ | ||
Q->rear = Q->front->next; | ||
free(Q->front); | ||
Q->front = Q->rear; | ||
} | ||
return OK; | ||
} | ||
//图的基本操作 | ||
|
||
Status LocateVex(MGraph *G,int v1,int v2) | ||
{ | ||
int i; | ||
int j; | ||
int m = 0; | ||
int n = 0; | ||
for (i = 0; i <= G->vexnum; i++) | ||
{ | ||
if (G->vexs[i]==v1) | ||
{ | ||
m = i; | ||
break; | ||
} | ||
} | ||
for (j = 0; j <= G->vexnum; j++) | ||
{ | ||
if (G->vexs[j] == v2) | ||
{ | ||
n = j; | ||
break; | ||
} | ||
} | ||
G->arcs[i][j].adj = 1;//两点之间有连线,弧值为1; | ||
G->arcs[j][i] = G->arcs[i][j]; | ||
return OK; | ||
} | ||
|
||
//构建图 | ||
Status CreateUDN(MGraph *G) | ||
{ | ||
int i; | ||
int j; | ||
//根据用例直接赋值。 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 虽然就题论题你这里这样写是能得到正确答案的,但建议以后在实际应用编程时,尽量把这种参数配置类的工作交给调用者(函数)在调用函数时执行传参操作,代码的 |
||
G->vexnum = 9; | ||
G->arcnum = 12; | ||
for (i = 1; i <= G->vexnum; i++) | ||
{ | ||
G->vexs[i] = i;//构建顶点向量; | ||
} | ||
for (i = 0; i <= G->vexnum; i++)//初始化邻接矩阵; | ||
{ | ||
for (j = 0; j <= G->vexnum; j++) | ||
{ | ||
G->arcs[i][j].adj = INFINITY; | ||
G->arcs[i][j].info = NULL; | ||
} | ||
} | ||
//构建邻接矩阵; | ||
LocateVex(G, 1, 2); | ||
LocateVex(G, 1, 3); | ||
LocateVex(G, 1, 4); | ||
LocateVex(G, 1, 7); | ||
LocateVex(G, 2, 3); | ||
LocateVex(G, 4, 5); | ||
LocateVex(G, 4, 6); | ||
LocateVex(G, 5, 6); | ||
LocateVex(G, 6, 8); | ||
LocateVex(G, 7, 8); | ||
LocateVex(G, 7, 9); | ||
LocateVex(G, 8, 9); | ||
|
||
return OK; | ||
} | ||
|
||
//找出第一个邻接点 | ||
int FirstAdjVex(MGraph *G, int u) | ||
{ | ||
int i; | ||
for (i = 1; i <= G->vexnum; i++) | ||
{ | ||
if (G->arcs[u][i].adj == 1) | ||
{ | ||
return i; | ||
} | ||
} | ||
return -1; | ||
} | ||
|
||
//找出下一个邻接点 | ||
int NextAdjvex(MGraph *G, int u, int w) | ||
{ | ||
int i; | ||
for (i = w + 1; i <= G->vexnum; i++) | ||
{ | ||
if (G->arcs[u][i].adj == 1) | ||
{ | ||
return i; | ||
} | ||
} | ||
return -1; | ||
} | ||
//广度优先遍历图,求两点a,b间的最短路径; | ||
Status BFSTraverse(MGraph*G, LinkQueue *Q,int a,int b) | ||
{ | ||
|
||
int v; | ||
int u = 0; | ||
int w = 0; | ||
bool visited[MAX_VERTEX_NUM]; | ||
for (v = 1; v <= G->vexnum; v++) | ||
{ | ||
visited[v] = false; //标记数组,标记图中已访问的点 | ||
} | ||
|
||
EnQueue(Q, a); //a先入队列; | ||
while (QueueEmpty(Q)!= true) | ||
{ | ||
DeQueue(Q, &u); | ||
for (w = FirstAdjVex(G, u); w >=0; w = NextAdjvex(G, u, w)) | ||
{ | ||
if (visited[w] == false)//判断w是否已经访问过 | ||
{ | ||
visited[w] = true; | ||
EnQueue(Q, w); | ||
} | ||
if (w == b) | ||
{ | ||
break; | ||
} | ||
} | ||
if (w == b) | ||
{ | ||
break; | ||
} | ||
} | ||
return OK; | ||
} | ||
|
||
Status print(LinkQueue *Q,int a) | ||
{ | ||
if (Q->rear->data == a) | ||
{ | ||
printf("%d->%d\n", a, a); | ||
return OK; | ||
} | ||
|
||
int i = 0; | ||
int j; | ||
int num[MAX_VERTEX_NUM] = { 0 }; | ||
while (Q->rear->data!=a)//倒序进入数组 | ||
{ | ||
num[i] = Q->rear->data; | ||
Q->rear = Q->rear->pre; | ||
i++; | ||
} | ||
printf("%d", a); | ||
for (j = i - 1; j >= 0; j--) | ||
{ | ||
printf("->%d", num[j]); | ||
} | ||
|
||
|
||
printf("\n"); | ||
return OK; | ||
} | ||
int main() | ||
{ | ||
int i; | ||
int j; | ||
|
||
MGraph Graph; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. C/C++代码中,我们习惯于使用小写字母打头的单词表示一个 |
||
CreateUDN(&Graph); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
for (i = 1; i <= Graph.vexnum; i++) | ||
{ | ||
for (j = 1; j <= Graph.vexnum; j++) | ||
{ | ||
LinkQueue Q; | ||
InitQueue(&Q); | ||
printf("%d<->%d:", i, j); | ||
BFSTraverse(&Graph, &Q, i, j); | ||
print(&Q, i); | ||
DestroyQueue(&Q); | ||
} | ||
} | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
按照我们课件中的操作定义,
LocateVex
应该是实现若G中存在顶点u,则返回该顶点在图中“位置” ;否则返回其它信息
,你这里实际的连线操作是不是用InsertArc
更合适?