码迷,mamicode.com
首页 > 其他好文 > 详细

3.2 网状关系:图(2)

时间:2016-07-19 09:27:39      阅读:167      评论:0      收藏:0      [点我收藏+]

标签:

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 }

 

3.2 网状关系:图(2)

标签:

原文地址:http://www.cnblogs.com/wozixiaoyao/p/5683143.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!