图(Graph)的常用代码集合
来源:互联网 发布:php后端登录代码 编辑:程序博客网 时间:2024/06/16 07:12
图的相关概念请查阅离散数学图这一章或者数据结构中对图的介绍。代码来自课本。
/*Graph存储结构*///邻接矩阵表示法#define MAX_VERTEX_NUM 20 /*最多顶点个数*/#define INFINITY 32768 /*表示极大值,即∞*//*图的种类:DG表示有向图,DN表示有向网,DUG表示无向图,UDN表示无向网*/typedef enum {DG, DN, UDG, UDN} GraphKind; /*枚举类型*/typedef char VertexData /*假设顶点数据为字符型*/typedef struct ArcNode { AdjType adj; /*对于无权图,用1或0表示是否相邻;对带权图,则为权值类型*/ OtherInfo info;} ArcNode;typedef struct { VertexData vertex[MAX_VERTEX_NUM]; /*顶点向量*/ ArcNode arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; /*邻接矩阵*/ int vexnum,arcnum; GraphKind kind;} AdjMartrix; /*(AdjMartrix Matrix Graph)*//*采用邻接矩阵表示法创建有向图*/int LocateVertex(AdjMartrix *G, VertexData v) { /*定位顶点位置函数*/ int j = ERROR, k; for(k = 0; k < G->vexnum; k++) { if(G->vertex[k] == v) { j = k; break; } } return j;}int CreateDN(AdjMartrix *G) { int i,j,k,weight; VertexData v1,v2; scanf("%d,%d", &G->arcnum; &G->vexnum); /*输入图的顶点数和弧数*/ for(i = 0; i < G->vexnum; i++) { /*初始化邻接矩阵*/ for(j = 0; j < G->vexnum; j++) { G->arcs[i][j].adj = INFINITY; } } for(i = 0; i < G->vertex; i++) { /*输入图的顶点*/ scanf("%c", &G->vertex)[i]; } for(k = 0; k < G->arcnum; k++) { /*输入一条弧的两个顶点和权值*/ scanf("%c,%c,%d", &v1,&v2,&weight); i = LocateVertex_M(G, v1); j = LocateVertex_M(G, v2); G->arcs[i][j].adj = weight; /*建立弧*/ } return OK;}//邻接表表示法#define MAX_VERTEX_NUM 20typedef enum {DG, DN, UDG, UDN} GraphKind;typedef struct ArcNode { int adjvex; /*该弧指向顶点的位置*/ struct ArcNode *nextarc; /*指向下一条弧的指针*/ OtherInfo;} ArcNode;typedef struct VerNode { VertexData data; ArcNode *firstarc;} VerNode;typedef struct { VertexNode vertex[MAX_VERTEX_NUM]; int vexnum,arcnum; GraphKind kind;} AdjList; /*Adjacency List Graph*///十字链表#define MAX_VERTEX_NUM 20typedef enum {DG, NG, UDG, UDN} GraphKind;typedef struct ArcNode { int tailvex,headvex; struct ArcNode *hlink, *tlink;} ArcNode;typedef struct VertexNode { VertexData data; ArcNode *firstin, *firstout;} VertexNode;typedef struct { VertexNode vertex[MAX_VERTEX_NUM]; int vexnum,arcnum; //图的顶点数和弧数 GraphKind kind;} OrthList;/*创建图的十字链表*/void CrtOrthList(OrthList *g) {/*从终端输入n个顶点的信息和e条弧的信息,以建立一个有向图的十字链表*/ scanf("%d,%d", &n,&e); /*从键盘输入图的顶点个数和弧的个数*/ g->vertex = n; g->vertex = e; for(i = 0; i < n; i++) { /*初始化顶点结点*/ scanf("%c", &(g->vertex[i].data)); g->vertex[i].firstin = NULL; g->vertex[i].firstout = NULL; } for(k = 0; k < e; k++) { /*创建弧结点,建立弧结点个顶点的连接*/ scanf("%c,%c", &vt,&vh); i = LocateVertex(g, vt); j = LocateVertex(g, vh); p = (ArcNode *)malloc(sizeof(ArcNode)); p->tailvex = i; p->headvex = j; p->tlink = g->vertex[i].firstout; g->vertex[i].firstout = p; p->hlink = g->vertex[j]; g->vertex[j].firstin = p; }} /*CrtOrthList*//*邻接多重表*/#define MAX_VERTEX_NUM 20typedef struct EdgeNode { int mark,ivex,jvex; struct EdgeNode *ilink, *jlink;} EdgeNode;typedef struct { VertexData data; EdgeNode *firstedge;} VertexNode;typedef struct { VertexNode vertexp[MAX_VERTEX_NUM]; int vernum,arcnum; GraphKind kind;} AdjMultiList;/*图的深度遍历算法*/#define True 1#define False 0#define Error -1#define OK 1int visited[MAX_VERTEX_NUM]; /*初始化标准数组*/void TraverseGraph(Graph g) {/*在图g中寻找未访问的顶点作为起始点,并调用深度优先搜索过程进行遍历。Graph表示图的一种存储结构,如邻接矩阵或者邻接表等*/ for(vi = 0; vi < g.vexnum; vi++) Visited[vi] = False; /*访问标志数组*/ for(vi = 0; vi < g.vexnum; vi++) { //循环调用深度优先遍历连通子图,若g是连通图,则此 if(!visted[vi]) DepthFirstSearch(g,vi); //仅调用一次 } } /*TraverseGraph*//*深度优先遍历v0所在的连通子图*/void DepthFirstSearch(Graph g, int v0) { visit(v0); visit[v0] = True; /*访问顶点v0,修改访问变量*/ w = FirstAdjVertex(g, v0); while(w != -1) { if(!visited[w]) DepthFirstSearch(g, w); /*递归调用DepthFirstSearch*/ w = NextAdjVertex(g, v0, w); /*找下一个邻接点*/ }} /*DepthFirstSearch*//*采用邻接矩阵的DepthFirstSearch*/void DepthFirstSearch(AdjMartrix g, int v0) { visit(v0); visited[vo] = True; for(vj = 0; vj < g.vexnum; vj++) { if(!visited[vj] && g.arcs[v0][vj].adj == 1) { //未访问过且路径存在 DepthFirstSearch(g, vj); } }} /*DepthFirstSearch*//*采用邻接表的DepthFiirstSearch*/void DepthFirstSearch(AdjList g, int v0) { visit(v0); visited[v0] = True; p = g.vertex[v0].firstarc; while(p != NULL) { if(!visited[p->adjvex]) DepthFirstSearch(g, p->adjvex); p = p->nextarc; }} /*DepthFirstSearch*//*非递归形式的DepthFirstSearch*/void DepthFirstSearch(Graph g, int v0) {/*从v0出发深度优化搜索图g*/ InitStack(&s); Push(&S, v0); while(!is Empty(S)) { Pop(&S, &v); if(!visited[v]) { visit(v); visited[v] = True; w = FirstAdjVertex(g, v); while(w != -1) { if(!visted[w]) { Push(&S, w); } w = NextAdjVertex(g, v, w); /*求v相对于w的下一个邻接点*/ } } }}/*广度优先搜索图g中v0所在的连通子图*/void BreadthFirstSearch(Graph g, int v0) { visit(v0); visited[v0] = True; InitQueue(&Q); EnterQueue(&Q, v0); while(Empty(&Q, v0)) { DeleteQueue(&Q, &v); w = FirstAdjVertex(g, v); while(w != -1) { if(!visited[w]) { visit(w); visited[w] = True; EnterQueue(&Q, w); } w = NextAdjVertex(g, v, w); } }}/*图的应用*//*深度优先找出从顶点u到v的简单路径*/int *pre;void one_path(Graph *G, int u, int v) { int i; pre = (int *)malloc(G->vexnum * sizeof(int)); for(i = 0; i < G->vexnum; i++) { /*初始化,置-1*/ pre[i] = -1; } pre[u] = -2; /*将pre[u]置-2,表示已访问过,且没有前驱*/ DFS_path(G, u, v); /*用深度优先算法找出一条从u到v的简单路径*/ free(pre);}int DFS_path(Graph *G, int u, int v) { int j; for(j = firstadj(G, u)); j >= 0; j = nextadj(G, u, j)) { if(pre[j] == -1) { //不等于-1则参数有误 pre[j] = u; if(j == v) { print_path(pre, v); //从v0开始,沿着pre[]中保留的前驱指针输出路径(直到-2) } else if(DFS_path(G, j, v)); return 1; } } return 0;}/*求图的最小生成树*//*prim算法(加点法)*/struct { int adjvex; int lowcost;} closedge[MAX_VERTEX_NUM]; /*求最小生成树时的辅助数组*/MiniSpanTree_Prim(AdjMartrix gn, int u) {/*从顶点u出发,按prim算法构造连通网gn的最小生成树,并输出生成时的每条边*/ closedge[u].lowcost = 0; /*初始化*, U = {u}*/ for(i = 0; i < gn.vexnum; i++) { if(i != u) { /*对V-U的顶点i,初始化closedge[i]*/ closedge[i].adjvex = u; closedge[i].lowcost = gn.arcs[u][i].adj; } } for(e = 1; e < gn.vexnum - 1; e++) { /*找n-1条边*/ v = Mimium(closedge); /*closedge中存有当前最小边(u,v)的信息*/ printf(u, v); /*输出生成树的当前最小边(u,v)*/ closedge[v].lowcost = 0; /*将顶点v纳入U集合*/ for(i = 0; i < gn.vexnum; i++) { /*顶点v纳入U集合后,更新closedge[i]*/ if(gn.arcs[v][i].adj < closedge[i].lowcost) { closedge[i].lowcost = gn.arcs[v][i].adj; closedge[i].adj = v; } } }}
0 0
- 图(Graph)的常用代码集合
- 常用的集合元素使用范例代码
- boost graph read_graphml 要解析graph property(图的属性)要自己给boost graph加代码
- javascript常用代码集合
- Android 常用代码集合
- Android 常用代码集合
- Android 常用代码集合
- Android常用代码集合
- Android 常用代码集合
- JavaScript常用代码集合
- 常用代码集合
- Android 常用代码集合
- 构建Graph图常用技术
- 构建Graph图常用技术
- 图论中特殊的集合 Sets in graph
- Asp.net非常常用的代码集合(51个)
- 二叉树的性质和常用操作代码集合
- 转载:Android 常用代码集合
- n位数乘一位数
- 奋斗吧,程序员——第三十六章 落花人独立,微雨燕双飞
- 二人牛牛与通比牛牛
- 搜索Maven仓库
- 文件操作函数
- 图(Graph)的常用代码集合
- JAVA相关的视频学习视频,内容较多
- PAT 沙漏
- iOS 跳转到系统的设置界面
- 选择法排序
- 二维码的纠错等级
- 线性探测可再散列的散列
- 学习笔迹——DisplayImageOptions,网络图片显示
- linux 父进程中不阻塞不轮询回收子进程的两种方