图(Graph)的常用代码集合

来源:互联网 发布:php后端登录代码 编辑:程序博客网 时间:2024/06/16 01:45

图的相关概念请查阅离散数学图这一章或者数据结构中对图的介绍。代码来自课本。

/*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
原创粉丝点击