图论

来源:互联网 发布:数据库主键怎么定义 编辑:程序博客网 时间:2024/05/22 03:13

图论

这篇文章介绍了几种数据结构中图的算法,最简单的图的搜索dfs和bfs,到高级图的各种算法,如最小生成树,最短路径,关键路径。

图的存储结构

typedef struct{    int arc[MAXVEX][MAXVEX];    int numVertexes,numEdges;}MGraph;

最小生成树Prim算法

这个算法的思想是从任意的一个根节点开始开始,一直长大到覆盖图中所有的节点为止。这边电脑演示比较麻烦,于是手写演示。

void MiniSpanTree_Prim(MGraph G){    int min,i,j,k;    int adjvex[MAXVEX];   //保存相关顶点的下标     int lowcost[MAXVEX]; //保存顶点间的权值     lowcost[0] = 0;    adjvex[0] = 0;    for(i=0;i<G.numVertexes;i++)    {        lowcost[i] = G.arc[0][i];  //先将第一个顶点包含进去         adjvex[i] = 0;    }    for(i=1;i<G.numVertexes;i++)    {        min = INFINITY;        j = 1;k=0;        while(j<G.numEdges)        {            if(lowcost[j]!=0 && lowcost[j]<min)  //选择当前最小权值的大小和下标             {                min = lowcost[j];                k = j;            }            j++;        }        printf("(%d,%d)",adjvex[k],k); //输出下标和相连的顶点         lowcost[k] = 0;        for(j=1;j<G.numVertexes;j++) //找与k相连的最小的权值的点。         {            if(lowcost[j] != 0 && G.arc[k][j]<lowcost[j])            {                lowcost[j] = G.arc[k][j];                adjvex[j] = k;            }        }    }}

这个算法还要慢慢看。

Kruskal算法

除了上面的算法之外,还有一种我认为更加经典的算法就是这个了。先贴代码,再解释。

typedef struct{    int begin;    int end;    int weight;}Edge;void Swapn(Edge *edges,int i,int j){    int temp;    temp = edges[i].begin;    edges[i].begin = edges[j].begin;    edges[j].begin = temp;    temp = edges[i].end;    edges[i].end = edges[j].end;    edges[j].end = temp;    temp = edges[i].weight;    edges[i].weight = edges[j].weight;    edges[j].weight = temp;}void sort(Edge edges[],MGraph *G){    int i,j;    for(i=0;i<G->numEdges;i++)        for(j=i+1;j<G->numEdges;j++)            if(edges[i].weight>edges[j].weight)                Swapn(edges,i,j);}int find(int *parent,int f){    while(parent[f]>0)        f = parent[f];    return f;}void MinSpanTree_Kruskal(MGraph G){    int i,j,n,m;    int k = 0;    int parent[MAXVEX];    Edge edges[MAXEDGE];    for(i=0;i<G.numVertexes;i++)    {        for(j=i+1;j<G.numVertexes;j++)        {            if(G.arc[i][j]<65535)            {                edges[k].begin = i;                edges[k].end = j;                edges[k].weight = G.arc[i][j];                k++;            }        }    }    sort(edges,&G);    for(i=0;i<G.numEdges;i++)        parent[i] = 0;    for(i=0;i<G.numEdges;i++)    {        n = find(parent,edges[i].begin);        m = find(parent,edges[i].end);        if(n!=m)        {            parent[n] = m;            printf("%d %d %d\n",edges[i].begin,edges[i].end,edges[i].weight);        }    }}

最短路径

最短路径需要解决的问题是求源点到各个点之间的最短路。这里还分单源最短路径和多源最短路径。单源最短路径算法就是Dijkstra算法,多源最短路径是Floyd算法。

Dijkstra算法

void ShortPath_Dijkstra(MGraph G,int v0,Patharc *P,ShortPathTable *D){    int v,w,k,min;    int final[MAXVEX];    for(v=0;v<G.numVertexes;v++)    {        final[v] = 0;        (*D)[v] = G.arc[v0][v];        (*P)[v] = 0;    }    (*D)[v0] = 0;    final[v0] = 1;    for(v=1;v<G.numVertexes;v++)    {        min = INFINITY;        for(w = 0;w<G.numVertexes;w++)        {            if(!final[w] && (*D)[w] < min)            {                k = w;                min = (*D)[w];            }        }        final[k] = 1;        for(w=0;w<G.numEdges;w++)        {            if(!final[w] && (min + G.arc[k][w] < (*D)[w] ))            {                (*D)[w] = min + G.arc[k][w];                (*P)[w] = k;            }        }    }}

应该代码能够看得懂的。

Floyd算法

void ShortPath_Floyd(MGraph G,Pathmatirx *P,ShortPathTable *D){    int v,w,k;    for(v=0;v<G.numVertexes;v++)    {        for(w=0;w<G.numVertexes;w++)        {            (*D)[v][w] = G.arc[v][w];            (*P)[v][w] = w;        }    }    for(k=0;v<G.numVertexes;k++)    {        for(v = 0;v<G.numVertexes;v++)        {            for(w = 0;w<G.numVertexes;w++)            {                if((*D)[v][w] > (*D)[v][k] + (*D)[k][w])                {                    (*D)[v][w] = (*D)[v][k]+(*D)[k][w];                    (*P)[v][w] = (*P)[v][k];                }            }        }    }}

简单粗暴吧。

今天终于将图这部分算法搞懂了,以前一直想学却没有精力和毅力来学习。

1 0
原创粉丝点击