您的位置:首页 > 理论基础 > 数据结构算法

二哥学算法之图(开篇)

2015-03-17 18:29 169 查看
图论问题几乎涉及整个计算机科学,成千上百的计算问题几乎都可以归纳总结为图论问题。生活中也有很多需要图论的例子,如以后为大家提到的最大二分图匹配,最小费用最大流,单源最短路径等等,我对这部分也只是略知一个,有错误之处还望大家指出。

先定义一下图:一个图(Graph)可以看做是边和点的集合。我们有G=(V,E) V(vertex)表示顶点集,E(Edge)表示边集。每一条边就是一个点对(u,v),如果一个点对是有序的,比如说只能从u到v,从v到u是 非法的;则(u,v)这条边就是有序的。反之,则有无向图。即(u,v),(v,u)都是合法的。图常常还会具有第三种属性,叫做权(weight)或值(cost)。

现在给大家介绍两种图的表示方法。邻接链表和邻接矩阵。

邻接矩阵表示起来相对来说比较简单即通过一个二维数组Array[N
,对于每一条边(u,v),可以置Array[u[[v]=1,如果边上有权值。则可以用一个很大或者很小的值表示不存在的边。

下面是一个用邻接矩阵表示图的示例代码:

#include <iostream>
#define INIFY 66553
#define N 8   //顶点数目
int array

int Edge_Numbers;
int main(void){
int i,j,k;
std::cout<<"请输入顶点数: "<<std::endl;
std::cin>>Edge_Numbers;
//初始化顶点
for(i=0;i<N;i++)
for(j=0,j<N;j++)
array[i][j]=INIFY;
std::cout<<"请输入顶点关系和权值"<<std::endl;
for(int m=0;m<Edge_Numbers;m++){
std::cin>>i>>j>>k;
array[i][j]=k;
//如果是无向图
array[j][i]=array[i][j]=K;
}
return 0;
}


用这种方法表示图很简单,不要很明显看以看出。图的空间需求为

,如果图的边不是很多,那么这种表示方法就有点浪费内存了。如果图是稠密的,

这种方法就是很合适的。

另一方面如果图不是稠密的,换句话说如果是稀疏的,则更好的解决办法就是用上面提高的邻接链表了。对于每一个顶点,我们使用一个表来存储所有的邻接顶点。此时空间需求度为

。下面我写一个示例性的邻接表实现(质量很渣渣,不要模仿,仅供参考)

#include <iostream>
#define N 4
int array[N][N];

//邻接表
struct Edge{
int from;
int to;
int weight;
Edge *next;
Edge(int _from=-1,int _to=-1,int _weight=0):
from(_from),to(_to),weight(_weight){
}
};
Edge *edge[N]={nullptr,nullptr,nullptr};
void add_edge(){
int u,v,k;
Edge *p=nullptr;
std::cout<<"请输入顶点i,j和k;以-2作为结束。"<<std::endl;
while(std::cin>>u>>v>>k&&u!=-2,v!=-2){
p=new Edge;
p->from=u,p->to=v,p->weight=k,p->next=nullptr;
p->next=edge[u];
edge[u]=p;
}
}
void print_edge(Edge *p){
Edge *v;
std::cout<<"和"<<p->from<<"邻接的顶点及其权重值如下: "<<std::endl;
for(v=p;v!=nullptr;p=p->next,v=p)
std::cout<<v->to<<" weight:"<<v->weight<<std::endl;
}
int main(void){
add_edge();
print_edge(edge[1]);
return 0;
}


以上;下篇为大家带来图的BFS和DFS。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  算法 数据结构