图
图是一种重要的数据结构,可以用来描述很多实际问题,因此得到了广泛的应用。最典型的应用领域有电路分析、寻找最短路径、项目规划、鉴别化合物、统计力学、遗传学、控制论等学科中。图的主要特点:它的每一个顶点可以与多个其他顶点相关联,各顶点之间的关系时任意的。
1、图的一些基本概念
路径:在图G=(V,E)中,若从顶点vi出发沿着一些边经过若干顶点vp1, vp2,vp3,vp4...vpm 到达顶点vj 则称顶点序列(vi, vp1, vp2,vp3,vp4...vpm, vj)为从顶点i到顶点j的一条路径。
路径长度:不带权的图,路径长度是指此路径上边的条数。带权图,路径长度是指路径上各个边上的权值之和。
简单路径:若路径上各个顶点没有重复的,则称该路径为简单路径。若第一个顶点和最后一个顶点重合,则称这样的路径为回路。
连通图和连通分量:在无向图中,从顶点一到顶点二有路径,则称这两个顶点是连通的,若图中的任一对顶点都是连通的,则称此图是连通的。非连通图的最大连通子图称为该图的连通分量。
强连通图和强连通分量:在有向图中,若任意两个顶点之间都有两个路径,则称此图是强连通的,非强连通图的极大连通子图是强连通分量。
生成树:一个无向连通图的生成树是它的极小连通子图。
2、图的C++实现
图的邻接表表示法:
声明一个数组表示各个顶点,以每个顶点为头结点,链接和这个结点相连的边。下图是一个示例图片:

抽象数据类型表示:
/*
有向图边结构体
*/
struct GraphEdge
{
int cost; //边的权值
int edgedata; //边的顶点值
GraphEdge *nextedge; //下一个边
GraphEdge(int cost,int edgedata)
{
this->cost=cost;
this->edgedata=edgedata;
this->nextedge=NULL;
}
};
/*
图顶点:结构体表示,包含顶点的值和边链表指针域,
顶点表使用数组来表示。
*/
struct Vertex
{
int data; //顶点的值
GraphEdge *edgehead; //边链表的头指针
};
//图类
class LinkedGraph
{
public:
//构造函数析构函数
LinkedGraph()
{
//初始化参数值
v=new Vertex[9]; //创建顶点表数组
//加入检测语句
if(v==NULL)cout<<"未分配成功"<<endl;
for(int i=0;i<9;i++)
v[i].edgehead=NULL; //这里需要用点运算符进行操作
}
~LinkedGraph()
{
}
//建立图、输出图
void InitGraphOutput(LinkedGraph *lg);
//深度优先搜索和广度优先搜索
void DFSGraph(LinkedGraph *lg); //深度优先遍历
void BFSGraph(LinkedGraph *lg); //广度优先遍历
private:
//声明结点的个数,并分配空间:不能只声明不定义和分配存储空间
Vertex *v;
};
建立邻接表表示的图(带权无向图)算法:
1、输入顶点,顶点数组表示。
2、输入边,将每个顶点之间有关系的边链接起来。
3、相当于插入顶点,插入边。
代码:
void LinkedGraph::InitGraphOutput(LinkedGraph *lg)
{
int data; //顶点值
int dest,cost;
int i=0;
while(i<9) //建立图的顶点数组和这个顶点链接的边
{
//输入顶点
cout<<"请输入顶点值:"<<endl;
cin>>data;
lg->v[i].data=data; //要用点运算符来操作结构体的成员
GraphEdge *q,*p=lg->v[i].edgehead; //声明两个指针,一个用于指向当前顶点的边链表头指针,一个用来辅助
cin>>dest>>cost; //输入这个顶点链接的边,以权值为0结束
int edgenum=0; //用来记录边数,用于不同的链接方式,局部变量的位置
while(cost!=0)
{
edgenum++;
if(edgenum<=1)
{
//分配一个存储空间给q,如果是第一条边
q=new GraphEdge(cost,dest);
if(q==NULL)cout<<"未分配成功"<<endl;
//链接
lg->v[i].edgehead=q; //记住这一句
p=q;
q=q->nextedge;
}
else
{
//bug:只能链入两条边
cout<<"第二条边链接成功"<<endl;
//还有其他边
q=new GraphEdge(cost,dest);
p->nextedge=q;
p=p->nextedge;
q=q->nextedge;
}
cout<<"请继续输入这个顶点对应的边的值和权值:"<<endl;
cin>>dest>>cost;
}
i++; //插入顶点的操作
}
cout<<"-------------输出这个图:-------------"<<endl;
//输出这个图
for(int i=0;i<9;i++)
{
cout<<lg->v[i].data<<endl;
GraphEdge *p=lg->v[i].edgehead;
if(p==NULL)cout<<"这个指针出现问题"<<endl<<endl;
while(p!=NULL)
{
cout<<lg->v[i].data<<"-->"<<p->edgedata<<" 权值为:"<<p->cost<<endl;
p=p->nextedge;
}
}
}
图的关联算法
1、克鲁斯卡尔
2、floyd
4、普里姆
5、Bellman-Ford
6、迪杰斯特拉
7、SPFA
8、拓扑排序
9、最短路径问题

浙公网安备 33010602011771号