标签:
3-8 AdjListGraph.c
1 #define VERTEX_MAX 20 //图的最大顶点数 2 typedef struct edgeNode 3 { 4 int Vertex; //顶点信息(序号或字母) 5 int weight; //权值 6 struct edgeNode *next; //指向下一个顶点指针 (当前顶点和指向的下一顶点构成一条边) 7 }EdgeNode; //邻接表边结构 8 9 typedef struct 10 { 11 EdgeNode* AdjList[VERTEX_MAX]; //指向每个顶点的指针 12 int VextexNum,EdgeNum; //图的顶点的数量和边的数量 13 int GraphType; //图的类型(0:无向图,1:有向图) 14 }ListGraph; //图的结构 15 16 void CreateGraph(ListGraph *G); //生成图的邻接表 17 void OutList(ListGraph *G); //输出邻接表 18 19 void CreateGraph(ListGraph *G) //构造邻接表结构图 20 { 21 int i,weight; 22 int start,end; 23 EdgeNode *s; 24 for(i=1;i<=G->VextexNum;i++)//将图中各顶点指针清空 25 G->AdjList[i]=NULL; 26 for(i=1;i<=G->EdgeNum;i++) //输入各边的两个顶点 27 { 28 getchar(); 29 printf("第%d条边:",i); 30 scanf("%d,%d,%d",&start,&end,&weight); //输入边的起点和终点 31 s=(EdgeNode *)malloc(sizeof(EdgeNode)); //申请保存一个顶点的内存 32 s->next=G->AdjList[start]; //插入到邻接表中 33 s->Vertex=end; //保存终点编号 34 s->weight=weight; //保存权值 35 G->AdjList[start]=s; //邻接表对应顶点指向该点 36 if(G->GraphType==0) //若是无向图,再插入到终点的边链中 37 { 38 s=(EdgeNode *)malloc(sizeof(EdgeNode)); //申请保存一个顶点的内存 39 s->next=G->AdjList[end]; 40 s->Vertex=start; 41 s->weight=weight; 42 G->AdjList[end]=s; 43 } 44 } 45 } 46 void OutList(ListGraph *G) 47 { 48 int i; 49 EdgeNode *s; 50 for(i=1;i<=G->VextexNum;i++) 51 { 52 printf("顶点%d",i); 53 s=G->AdjList[i]; 54 while(s) 55 { 56 printf("->%d(%d)",s->Vertex,s->weight); 57 s=s->next; 58 } 59 printf("\n"); 60 } 61 }
3-9 AdjListGraphTest.c
1 #include <stdio.h> 2 #include "3-8 AdjListGraph.c" 3 int main() 4 { 5 ListGraph G; //定义保存邻接表结构的图 6 printf("输入生成图的类型(0:无向图,1:有向图):"); 7 scanf("%d",&G.GraphType); //图的种类 8 printf("输入图的顶点数量和边数量:"); 9 scanf("%d,%d",&G.VextexNum,&G.EdgeNum); //输入图顶点数和边数 10 printf("输入构成各边的两个顶点及权值(用逗号分隔):\n"); 11 CreateGraph(&G); //生成邻接表结构的图 12 printf("输出图的邻接表:\n"); 13 OutList(&G); 14 getch(); 15 return 0; 16 }
3-10 GraphTrav.c
1 #include <stdio.h> 2 #include "3-6 AdjMatrixGraph.c" 3 #define QUEUE_MAXSIZE 30 //队列的最大容量 4 typedef struct 5 { 6 int Data[QUEUE_MAXSIZE]; //数据域 7 int head; //队头指针 8 int tail; //队尾指针 9 }SeqQueue; //队列结构 10 //队列操作函数 11 void QueueInit(SeqQueue *q); //初始化一个队列 12 int QueueIsEmpty(SeqQueue q); //判断队列是否空 13 int QueueIn(SeqQueue *q,int n); //将一个元素入队列 14 int QueueOut(SeqQueue *q,int *ch); //将一个元素出队列 15 16 //图操作函数 17 void DFSTraverse(MatrixGraph *G); //深度优先遍历 18 void BFSTraverse(MatrixGraph *G); //广度优先遍历 19 void DFSM(MatrixGraph *G,int i); 20 void BFSM(MatrixGraph *G,int i); 21 22 void QueueInit(SeqQueue *Q) //队列初始化 23 { 24 Q->head=Q->tail=0; 25 } 26 int QueueIsEmpty(SeqQueue Q) //判断队列是否已空,若空返回1,否则返回0 27 { 28 return Q.head==Q.tail; 29 } 30 int QueueIn(SeqQueue *Q,int ch) //入队列,成功返回1,失败返回0 31 { 32 if((Q->tail+1) % QUEUE_MAXSIZE ==Q->head) //若队列已满 33 return 0; //返回错误; 34 Q->Data[Q->tail]=ch; //将数据ch入队列 35 Q->tail=(Q->tail+1) % QUEUE_MAXSIZE; //调整队尾指针 36 return 1; //成功,返回1 37 } 38 int QueueOut(SeqQueue *Q,int *ch) //出队列,成功返回1,并用ch返回该元素值,失败返回0 39 { 40 if(Q->head==Q->tail) //若队列为空 41 return 0; //返回错误 42 *ch=Q->Data[Q->head]; //返回队首元素 43 Q->head=(Q->head+1) % QUEUE_MAXSIZE; //调整队首指针 44 return 1; //成功出队列,返回1 45 } 46 47 void DFSTraverse(MatrixGraph *G) //深度优先遍历 48 { 49 int i; 50 for(i=0;i<G->VertexNum;i++) //清除各顶点遍历标志 51 G->isTrav[i]=0; 52 printf("深度优先遍历结点:"); 53 for(i=0;i<G->VertexNum;i++) 54 if(!G->isTrav[i]) //若该点未遍历 55 DFSM(G,i); //调用函数遍历 56 printf("\n"); 57 58 } 59 void DFSM(MatrixGraph *G,int i) //从第i个结点开始,深度遍历图 60 { 61 int j; 62 G->isTrav[i]=1; //标记该顶点已处理过 63 printf("->%c",G->Vertex[i]);//输出结点数据 64 // printf("%d->",i); //输出结点序号 65 66 //添加处理节点的操作 67 for(j=0;j<G->VertexNum;j++) 68 if(G->Edges[i][j]!=MAXVALUE && !G->isTrav[i]) 69 DFSM(G,j); //递归进行遍历 70 } 71 void BFSTraverse(MatrixGraph *G) //广度优先 72 { 73 int i; 74 for (i=0;i<G->VertexNum;i++) //清除各顶点遍历标志 75 G->isTrav[i]=0; 76 printf("广度优先遍历结点:"); 77 for (i=0;i<G->VertexNum;i++) 78 if (!G->isTrav[i]) 79 BFSM(G,i); 80 printf("\n"); 81 } 82 void BFSM(MatrixGraph *G,int k) //广度优先遍历 83 { 84 int i,j; 85 SeqQueue Q; //创建循环队列 86 QueueInit(&Q); //初始化循环队列 87 88 G->isTrav[k]=1; //标记该顶点 89 printf("->%c",G->Vertex[k]); //输出第一个顶点 90 91 //添加处理节点的操作 92 QueueIn(&Q,k); //入队列 93 while (!QueueIsEmpty(Q)) //队列不为空 94 { 95 QueueOut(&Q,&i); //出队列 96 for (j=0;j<G->VertexNum;j++) 97 if(G->Edges[i][j]!=MAXVALUE && !G->isTrav[j]) 98 { 99 printf("->%c",G->Vertex[j]); 100 G->isTrav[j]=1; //标记该顶点 101 //处理顶点 102 QueueIn(&Q,j); //出队列 103 } 104 } 105 }
3-11 GraphTravTest.c
1 #include <stdio.h> 2 #include "3-10 GraphTrav.c" 3 int main() 4 { 5 MatrixGraph G; //定义保存邻接表结构的图 6 int path[VERTEX_MAX]; 7 int i,j,s,t; 8 char select; 9 do 10 { 11 printf("输入生成图的类型(0:无向图,1:有向图):"); 12 scanf("%d",&G.GraphType); //图的种类 13 printf("输入图的顶点数量和边数量:"); 14 scanf("%d,%d",&G.VertexNum,&G.EdgeNum); //输入图顶点数和边数 15 for(i=0;i<G.VertexNum;i++) //清空矩阵 16 for(j=0;j<G.VertexNum;j++) 17 G.Edges[i][j]=MAXVALUE; //设置矩阵中各元素的值为0 18 CreateMatrixGraph(&G); //生成邻接表结构的图 19 printf("邻接矩阵数据如下:\n"); 20 OutMatrix(&G); //输出邻接矩阵 21 DFSTraverse(&G); //深度优先搜索遍历图 22 BFSTraverse(&G); //广度优先搜索遍历图 23 printf("图遍历完毕,继续进行吗?(Y/N)"); 24 scanf(" %c",&select); 25 }while(select!=‘N‘ && select!=‘n‘); 26 getch(); 27 return 0; 28 }
3-12 Prim.c
1 #define USED 0 //已使用,加入U集合 2 #define NOADJ -1 //非邻接顶点 3 void Prim(MatrixGraph G)//最小生成树 4 { 5 int i,j,k,min,sum=0; 6 int weight[VERTEX_MAX];//权值 7 char tmpvertex[VERTEX_MAX];//临时顶点信息 8 9 for(i=1;i<G.VertexNum;i++) //保存邻接矩阵中的一行数据 10 { 11 weight[i]=G.Edges[0][i]; //权值 12 if(weight[i]==MAXVALUE) 13 tmpvertex[i]=NOADJ; //非邻接顶点 14 else 15 tmpvertex[i]=G.Vertex[0]; //邻接顶点 16 } 17 tmpvertex[0]=USED; //将0号顶点并入U集 18 weight[0]=MAXVALUE; //设已使用顶点权值为最大值 19 for(i=1;i<G.VertexNum;i++) 20 { 21 min=weight[0]; //最小权值 22 k=i; 23 for(j=1;j<G.VertexNum;j++) //查找权值最小的一个邻接边 24 if(weight[j]<min && tmpvertex[j]>0) //找到具有更小权值的未使用边 25 { 26 min=weight[j]; //保存权值 27 k=j; //保存邻接点序号 28 } 29 sum+=min;//累加权值 30 printf("(%c,%c),",tmpvertex[k],G.Vertex[k]); //输出生成树一条边 31 tmpvertex[k]=USED; //将编号为k的顶点并入U集 32 weight[k]=MAXVALUE; //已使用顶点的权值为最大值 33 for(j=0;j<G.VertexNum;j++) //重新选择最小边 34 if(G.Edges[k][j]<weight[j] && tmpvertex[j]!=0) 35 { 36 weight[j]=G.Edges[k][j]; //权值 37 tmpvertex[j]=G.Vertex[k]; //上一个顶点信息 38 } 39 } 40 printf("\n最小生成树的总权值为:%d\n",sum); 41 }
3-13 PrimTest.c
1 #include <stdio.h> 2 #include "3-6 AdjMatrixGraph.c" 3 #include "3-12 Prim.c" 4 int main() 5 { 6 MatrixGraph G; //定义保存邻接表结构的图 7 int path[VERTEX_MAX]; 8 int i,j,s,t; 9 char select; 10 do 11 { 12 printf("输入生成图的类型(0:无向图,1:有向图):"); 13 scanf("%d",&G.GraphType); //图的种类 14 printf("输入图的顶点数量和边数量:"); 15 scanf("%d,%d",&G.VertexNum,&G.EdgeNum); //输入图顶点数和边数 16 17 for(i=0;i<G.VertexNum;i++) //清空矩阵 18 for(j=0;j<G.VertexNum;j++) 19 G.Edges[i][j]=MAXVALUE; //设置矩阵中各元素的值为0 20 CreateMatrixGraph(&G); //生成邻接表结构的图 21 printf("邻接矩阵数据如下:\n"); 22 OutMatrix(&G); 23 24 printf("最小生成树的边为:\n"); 25 Prim(G); 26 27 printf("继续进行吗?(Y/N)"); 28 scanf(" %c",&select); 29 getchar(); 30 }while(select!=‘N‘ && select!=‘n‘); 31 getch(); 32 return 0; 33 }
3-14 Dijkstra.c
1 void Dijkstra(MatrixGraph G) 2 { 3 int weight[VERTEX_MAX];//某源点到各顶点的最短路径长度 4 int path[VERTEX_MAX];//某源点到终点经过的顶点集合的数组 5 int tmpvertex[VERTEX_MAX];//最短路径的终点集合 6 int i,j,k,v0,min; 7 printf("\n请输入源点的编号:"); 8 scanf("%d",&v0); 9 v0--; //编号自减1(因数组是从0开始) 10 for(i=0;i<G.VertexNum;i++) //初始辅助数组 11 { 12 weight[i]=G.Edges[v0][i]; //保存最小权值 13 if(weight[i]<MAXVALUE && weight[i]>0) //有效权值 14 path[i]=v0; //保存边 15 tmpvertex[i]=0; //初始化顶点集合为空 16 } 17 tmpvertex[v0]=1; //将顶点v0添加到集合U中 18 weight[v0]=0; //将源顶点的权值设为0 19 for(i=0;i<G.VertexNum;i++) 20 { 21 min=MAXVALUE; //将min中保存一个最大值 22 k=v0; //源顶点序号 23 for(j=0;j<G.VertexNum;j++) //在U集合中查找未用顶点的最小权值 24 if(tmpvertex[j]==0 && weight[j]<min) 25 { 26 min=weight[j]; 27 k=j; 28 } 29 tmpvertex[k]=1; //将顶点k加入集合U 30 for(j=0;j<G.VertexNum;j++) //以顶点k为中间点,重新计算权值 31 if(tmpvertex[j]==0 && weight[k]+G.Edges[k][j]<weight[j]) //有更小权值的路径 32 { 33 weight[j]=weight[k]+G.Edges[k][j]; //更新权值 34 path[j]=k; 35 } 36 } 37 printf("\n顶点%c到各顶点的最短路径为(终点 < 源点):\n",G.Vertex[v0]); 38 for(i=0;i<G.VertexNum;i++)//输出结果 39 { 40 if(tmpvertex[i]==1) 41 { 42 k=i; 43 while(k!=v0) 44 { 45 j=k; 46 printf("%c < ",G.Vertex[k]); 47 k=path[k]; 48 } 49 printf("%c\n",G.Vertex[k]); 50 }else 51 printf("%c<-%c:无路径\n",G.Vertex[i],G.Vertex[v0]); 52 } 53 }
3-15 DijkstraTest.c
1 #include <stdio.h> 2 #include "3-6 AdjMatrixGraph.c" 3 #include "3-14 Dijkstra.c" 4 int main() 5 { 6 MatrixGraph G; //定义保存邻接表结构的图 7 int path[VERTEX_MAX]; 8 int i,j,s,t; 9 char select; 10 do 11 { 12 printf("输入生成图的类型(0:无向图,1:有向图):"); 13 scanf("%d",&G.GraphType); //图的种类 14 printf("输入图的顶点数量和边数量:"); 15 scanf("%d,%d",&G.VertexNum,&G.EdgeNum); //输入图顶点数和边数 16 17 for(i=0;i<G.VertexNum;i++) //清空矩阵 18 for(j=0;j<G.VertexNum;j++) 19 G.Edges[i][j]=MAXVALUE; //设置矩阵中各元素的值为0 20 CreateMatrixGraph(&G); //生成邻接表结构的图 21 printf("邻接矩阵数据如下:\n"); 22 OutMatrix(&G); 23 24 printf("最短路径:\n"); 25 Dijkstra(G); 26 27 printf("继续进行吗?(Y/N)"); 28 scanf(" %c",&select); 29 getchar(); 30 }while(select!=‘N‘ && select!=‘n‘); 31 getch(); 32 return 0; 33 }
标签:
原文地址:http://www.cnblogs.com/wozixiaoyao/p/5683143.html