//目录

图论源代码——数据结构课堂作业

n(*≧▽≦*)n

 

 1 /*
 2 编写程序输出以邻接表为存储结构的无向图的各顶点的度。
 3 */
 4 /**********************************/
 5 /*文件名称:lab8_01.c                 */
 6 /**********************************/
 7 #include "ljb.h"
 8 /* 输出以邻接表为存储结构的无向图g的各顶点的度 */
 9 void degree(LinkedGraph g)
10 {
11     EdgeNode *p;
12     int i;
13     for (i=0; i<g.n; i++)
14     {
15         printf("%c's degree is ",g.adjlist[i].vertex);
16         p=g.adjlist[i].FirstEdge;
17         int cnt = 0;
18         while (p)
19         {
20             cnt++;
21             //printf("-->%d",p->adjvex);
22             p=p->next;
23         }
24         printf("%d\n",cnt);
25     }
26 
27 }
28 
29 
30 int main()
31 {
32     LinkedGraph g;
33     creat(&g,"g11.txt",0);      /*已知g11.txt中存储了图的信息*/
34     printf("\n The graph is:\n");
35     print(g);
36     degree(g);
37     return 0;
38 }
编写程序输出以邻接表为存储结构的无向图的各顶点的度
 1 /*
 2 图采用邻接表存储结构,编程对图进行广度优先遍历。
 3 */
 4 /**********************************/
 5 /*文件名称:lab8_02.c                 */
 6 /**********************************/
 7 #include "ljb.h"
 8 #include <queue>
 9 
10 using namespace std;
11 
12 
13 int visited[M];                  /*全局标志向量*/
14 /*请将本函数补充完整,并进行测试*/
15 void bfs(LinkedGraph g, int i)
16 {
17     visited[i] = true;
18     printf("%d ",i);
19     EdgeNode *p;
20     p=g.adjlist[i].FirstEdge;
21     /*从顶点i出发广度优先变量图g的连通分量*/
22     queue<int> Q;
23     while (p)
24     {
25         if(!visited[i])
26         {
27             printf("%d",i);
28             Q.push(i);
29         }
30         p=p->next;
31     }
32     while(!Q.empty()) {
33         int u = Q.front();
34         Q.pop();
35         bfs(g,u);
36     }
37 
38 }
39 
40 
41 /*函数功能:广度优先遍历图g
42   函数参数:邻接表g
43 */
44 int BfsTraverse(LinkedGraph g)
45 {
46     int i,count=0;
47     for (i=0; i<g.n; i++)
48         visited[i]=0;     /*初始化标志数组*/
49 
50     for (i=0; i<g.n; i++)
51         if (!visited[i])  /*vi未访问过*/
52         {
53             printf("\n");
54             count++;            /*连通分量个数加1*/
55             bfs(g,i);
56         }
57     return count;
58 }
59 
60 int main()
61 {
62     LinkedGraph g;
63     int count;
64     creat(&g,"g11.txt",0);          /*创建图的邻接表*/
65     printf("\n The graph is:\n");
66     print(g);
67     printf("广度优先遍历序列为:\n");
68     count=BfsTraverse(g);         /*从顶点0出发广度优先遍历图g*/
69     //printf("\n该图共有%d个连通分量。\n",count);
70     return 0;
71 }
图采用邻接表存储结构,编程对图进行广度优先遍历
 1 /*
 2     图采用邻接表存储结构,编程对图进行深度优先遍历。
 3 */
 4 
 5 #include "ljb.h"
 6 int visited[M];
 7 /*请将本函数补充完整,并进行测试*/
 8 
 9 void dfs(LinkedGraph g,int i)
10 {
11     /*从顶点i开始深度优先遍历图的连通分量*/
12     EdgeNode *p;
13     printf("visit vertex: %c \n",g.adjlist[i].vertex);/*访问顶点i*/
14     visited[i]=1;
15     p=g.adjlist[i].FirstEdge;
16     while (p)                 /*从p的邻接点出发进行深度优先搜索*/
17     {
18         if(!visited[p->adjvex]) {
19            // printf("%d\n",p->adjvex);
20             dfs(g,p->adjvex);
21         }
22         else p = p->next;
23     }
24 }
25 /*函数功能:深度优先遍历图
26   函数参数:图的邻接表g
27 */
28 void DfsTraverse(LinkedGraph g)
29 {
30     int i;
31     for (i=0; i<g.n; i++)
32         visited[i]=0;     /*初始化标志数组*/
33     for (i=0; i<g.n; i++)
34         if (!visited[i])  /*vi未访问过*/
35             dfs(g,i);
36 }
37 
38 int main()
39 {
40     LinkedGraph g;
41     creat(&g,"g11.txt",0);              /*创建图的邻接表*/
42     printf("\n The graph is:\n");
43     print(g);
44     printf("深度优先遍历序列为:\n");
45     DfsTraverse(g);                    /*从顶点0开始深度优先遍历图无向图g*/
46 }
图采用邻接表存储结构,编程对图进行深度优先遍历
 1 /*********************************************/
 2 /*           Prim求解最小生成树算法          */
 3 /*********************************************/
 4 #include "ljjz.h"
 5 
 6 typedef struct edgedata  /*用于保存最小生成树的边类型定义*/
 7 {
 8     int beg,en;     /*beg,en是边顶点序号*/
 9     int length;     /*边长*/
10 } edge;
11 
12 /*函数功能:prim算法构造最小生成树
13 函数参数:图的邻接矩阵g;边向量edge
14 */
15 void prim(Mgraph g, edge tree[M-1])
16 {
17     edge x;
18     int d,min,j,k,s,v;
19 
20     /* 建立初始入选点,并初始化生成树边集tree*/
21     int i;
22     int dis[M];
23     int vis[M];
24     int pre[M];
25     for(i=0; i<g.n; i++)
26     {
27         pre[i] = 0;
28         vis[i] = 0;
29         dis[i] = FINITY;
30         tree[i].length = FINITY;
31         tree[i].beg = tree[i].en = -1;
32     }
33 
34     int ans = 0;
35     dis[0] = 0;
36 
37     for(i=0; i<g.n; i++)
38     {
39         /*依次求当前(第k条)最小两栖边,并加入TE*/
40         int tmp = FINITY,k=-1;
41         for(j=0; j<g.n; j++)
42         {
43             if(!vis[j]&&dis[j]<tmp)
44             {
45                 tmp = dis[j];
46                 k = j;
47             }
48         }
49         if(tmp!=0) {
50             tree[i-1].length = tmp;
51             tree[i-1].beg = pre[k];
52             tree[i-1].en = k;
53         }
54 
55         vis[k] = 1;
56         ans +=tmp;
57         /*由于新顶点v的加入,修改两栖边的基本信息*/
58         for(s=0; s<g.n; s++) {
59             if(!vis[s]&&dis[s]>g.edges[k][s]) {
60                 dis[s] = g.edges[k][s];
61                 pre[s] = k;
62             }
63         }
64     }
65 
66     /*输出最小生成树*/
67     printf("\n最小生成树是:\n");/*输出最小生成树*/
68     for (j=0; j<=g.n-2; j++)
69         printf("\n%c---%c  %d\n",g.vexs[tree[j].beg],g.vexs[tree[j].en],tree[j].length);    //顶点信息
70     printf("\n最小生成树的根是: %c\n", g.vexs[0]);
71     printf("%d\n",ans);
72 }
73 
74 int  main()
75 {
76     Mgraph g;
77     edge  tree[M-1];  /*用于存放最小生成树的M-1条边*/
78     creat(&g,"g.txt",0);  /*创建无向图的邻接矩阵*/
79 
80     print(g);
81     prim(g,tree);        /*求解图的最小生成树*/
82     return 0;
83 
84 }
Prim求解最小生成树算法
 1 /***************************************************/
 2 /*          Dijkstra单源最短路径算法               */
 3 /***************************************************/
 4 #include "ljjz.h"   /*引入邻接矩阵创建程序*/
 5 #include "cstring"
 6 #include "algorithm"
 7 
 8 using namespace std;
 9 
10 typedef enum {FALSE,TRUE} boolean; /*false为0,true为1*/
11 typedef int dist[M];  /* 距离向量类型*/
12 typedef int path[M];  /* 路径类型*/
13 
14 /*函数功能:Dijkstra算法求解单源最短路径
15 函数参数:图的邻接矩阵g;源点v0;路径向量p;距离向量d
16 */
17 void dijkstra(Mgraph g,int v0,path p,dist d)
18 {
19     //boolean final[M]; /*表示当前元素是否已求出最短路径*/
20     //int i,k,j,v,min,x;
21     bool final[M];
22     memset(final,0,sizeof(final));
23 
24     /*  第1步  初始化集合S与距离向量d */
25     for(int i=0; i<g.n; i++)
26     {
27         p[i] = v0;
28         d[i] = g.edges[v0][i];
29     }
30 
31     final[v0] = true;
32     p[v0] = -1;
33 
34     for(int i=0; i<g.n-1; i++)
35     {
36         /* 第2步  依次找出n-1个结点加入S中   */
37         int tmp = FINITY,k = v0;
38         for(int j=0; j<g.n; j++)
39         {
40             if(final[j]) continue;
41             if(tmp>d[j])
42             {
43                 tmp = d[j];
44                 k = j;
45             }
46         }
47         /*第3步 修改S与V-S中各结点的距离*/
48         final[k] = true;
49         for(int j=0; j<g.n; j++)
50         {
51             if(final[j]) continue;
52             if(d[j]>d[k]+g.edges[k][j]&&g.edges[k][j]<FINITY)
53             {
54                 d[j] = d[k]+g.edges[k][j];
55                 p[j] = k;
56             }
57         }
58     }
59 }
60 /*函数功能:输出有向图的最短路径
61 函数参数:邻接矩阵g;路径向量p;距离向量d
62 */
63 void print_gpd(Mgraph g,path p,dist d)
64 {
65     int st[M],i,pre,top=-1;
66     for (i=0; i<g.n; i++)
67     {
68         printf("\nDistancd: %7d , path:",d[i]);
69         st[++top]=i;
70         pre=p[i];
71         while (pre!=-1)   /*从第i个顶点开始向前搜索最短路径上的顶点*/
72         {
73             st[++top]=pre;
74             pre=p[pre];
75         }
76         while (top>0)
77             printf("%2d",st[top--]);
78     }
79 }
80 /*---------- 主程序 ------------*/
81 int main()
82 {
83     Mgraph g;   /* 有向图 */
84     path p;     /* 路径向量 */
85     dist d;     /* 最短路径向量 */
86     int v0;
87     creat(&g,"g21.txt",1); /*假设图8.21所示的有向网G21的输入文件为g21.txt */
88     print(g);        /*输出图的邻接矩阵*/
89     printf("\n");
90     printf("请输入源点编号:");
91     scanf("%d",&v0);       /*输入源点*/
92     dijkstra(g,v0,p,d);   /*求v0到其他各点的最短距离*/
93     /*输出V0到其它各点的路径信息及距离*/
94     print_gpd(g,p,d);
95 
96     return 0;
97 }
Dijkstra单源最短路径算法
  1 /***************************************/
  2 /*             拓扑排序算法            */
  3 /***************************************/
  4 #include<stdlib.h>
  5 #include<stdio.h>
  6 #define M 20
  7 typedef char vertextype;
  8 typedef struct node       /*边结点类型定义*/
  9 {
 10     int adjvex;
 11     struct node *next;
 12 } edgenode;
 13 typedef struct de         /*带顶点入度的头结点定义*/
 14 {
 15     edgenode* FirstEdge;
 16     vertextype vertex;
 17     int id;                /*顶点的入度域*/
 18 } vertexnode;
 19 
 20 typedef struct            /*AOV网络的邻接表结构*/
 21 {
 22     vertexnode adjlist[M];
 23     int n,e;
 24 } AovGraph;
 25 
 26 void  creat(AovGraph *g,char *filename)       /*建立AOV网络的存储结构*/
 27 {
 28     int i,j,k;
 29     edgenode  *s;
 30     FILE *fp;
 31     fp=fopen(filename,"r");
 32     if (fp)
 33     {
 34         fscanf(fp,"%d%d",&g->n,&g->e);  /*输入图中的顶点数与边数*/
 35 
 36         for(i=0; i<g->n; i++)                      /*输入顶点值*/
 37         {
 38             fscanf(fp,"%1s",&g->adjlist[i].vertex);
 39             g->adjlist[i].FirstEdge=NULL;
 40             g->adjlist[i].id=0;       /*入度初始化为0*/
 41         }
 42         for(k=0; k<g->e; k++)
 43         {
 44             fscanf(fp,"%d%d",&i,&j);
 45             s=(edgenode*)malloc(sizeof(edgenode));
 46             s->adjvex=j;
 47             g->adjlist[j].id++;    /*顶点j的入度加1*/
 48             s->next=g->adjlist[i].FirstEdge;
 49             g->adjlist[i].FirstEdge=s;
 50         }
 51     }
 52 }
 53 
 54 void print(AovGraph g)
 55 {
 56     edgenode *p;
 57     int i;
 58     for (i=0; i<g.n; i++)
 59     {
 60         printf("%c %d   ", g.adjlist[i].vertex,g.adjlist[i].id);
 61         p=g.adjlist[i].FirstEdge;
 62         while (p)
 63         {
 64             printf("%d-->",p->adjvex);
 65             p=p->next;
 66         }
 67         printf("\n");
 68     }
 69 }
 70 /*函数功能:拓扑排序
 71 函数参数:AOV网邻接表存储结构变量g
 72 函数返回值:拓扑排序输出的顶点个数
 73 */
 74 int TopSort(AovGraph g)
 75 {
 76     int k=0,i,j,v, flag[M];
 77     int queue[M];  /*队列*/
 78     int h=0,t=0;
 79     edgenode* p;
 80     for (i=0; i<g.n; i++)  flag[i]=0; /*访问标记初始化*/
 81     /*先将所有入度为0的结点进队*/
 82     /*将程序补充完整*/
 83 
 84     for(int i=0; i<g.n; i++)
 85     {
 86         for(int j=0; j<g.n; j++)
 87         {
 88             if(g.adjlist[j].id==0)
 89             {
 90                 printf("%d ",j);
 91                 g.adjlist[j].id = -1;
 92                 p=g.adjlist[i].FirstEdge;
 93                 while (p)
 94                 {
 95                     g.adjlist[p->adjvex].id--;
 96                     //printf("%d-->",p->adjvex);
 97                     p=p->next;
 98                 }
 99                 break;
100             }
101         }
102     }
103 
104     return k;  //返回输出的顶点个数
105 }
106 int main()
107 {
108     int k=0;
109     AovGraph g;
110     creat(&g,"aov.txt");    /*假设图8.25所示的AOV网输入文件为aov.txt*/
111     printf("\n图8.27所示AOV网的邻接表是:\n");
112     print(g);
113     k=TopSort(g);
114     if(k<g.n) printf("\n该图存在环!\n");
115     return 0;
116 }
拓扑排序算法
posted @ 2016-12-20 19:16  小草的大树梦  阅读(1113)  评论(0编辑  收藏  举报