图的基本概念
图 G 是由两个集合:顶点集 V(G) 和边集 E(G) 组成的,记作G=( V(G),E(G) ),简称G=(V,E)。
V是顶点的有穷非空集合
E是两个顶点之间的关系,即边的有穷集合
在线性表中,元素个数可以为零,称为空表;
在树中,结点个数可以为零,称为空树;
在图中,顶点个数不能为零,但可以没有边。
不同结构中逻辑关系的对比
在线性结构中,数据元素之间仅具有线性关系;
在树结构中,结点之间具有层次关系;
在图结构中,任意两个顶点之间都可能有关系。
在线性结构中,元素之间的关系为前驱和后继;
在树结构中,结点之间的关系为双亲和孩子;
在图结构中,顶点之间的关系为邻接。
邻接矩阵
邻接表
4个常用操作
(1)邻接矩阵实现
int getfirstneighbor(Adj &G,int v)
{//取顶点v的第一个邻接顶点,若找不到,则返回-1
if(v!=-1)
{
for(int i=0;i<G.vum;i++)
{//顺序检查邻接矩阵的第v行
if(G.edge[v][i]>0&&G.edge[v][i]<INF)
{//INF表示定义的最大值
return i;
}
}
}
return -1;
}
int getnextneighbor(Adj &G,int v,int w)
{//给出v的某个邻接节点w的下一个邻接顶点
if(v!=-1&&w!=-1)
{
for(int i=w+1;i<G.vum;i++)
{
if(G.edge[v][i]>0&&G.edge[v][i]<INF)
{//INF表示定义的最大值
return i;
}
}
}
return -1;
}
int getvalue(Adj &G,int v)
{//取v的值
if(v!=-1)
{
return G.Vlist[v];
}
else return -1;
}
int getweight(Adj &G,int v,int w)
{//给出v、w的边权值
if(v!=-1&&w!=-1)
{
return G.edge[v][w];
}
else return -1;
}
(2)邻接表实现
int getfirstneighbor(Adj &G,int v)
{//取顶点v的第一个邻接顶点,若找不到,则返回-1
if(v!=-1)
{
Enode *p=G.Vlist[v].adj;
if(p!=NULL)//对应边链表第一个边结点存在
{
return p->dest;
}
}
return -1;
}
int getnextneighbor(Adj &G,int v,int w)
{//给出v的某个邻接节点w的下一个邻接顶点
if(v!=-1&&w!=-1)
{
Enode *p=G.Vlist[v].adj;
while(p!=NULL&&p->dest!=w) p=p->link;
if(p!=NULL&&p->link!=NULL)
{
return p->link->dest;
}
}
return -1;
}
int getvalue(Adj &G,int v)
{//取v的值
if(v!=-1)
{
return G.Vlist[v].data;
}
else return -1;
}
int getweight(Adj &G,int v,int w)
{//给出v、w的边权值
Enode *p=G.Vlist[v].adj;
while(p!=NULL&&p->dest!=w) p=p->link;
if(p!=NULL&&p->link!=NULL)
{
return p->cost;
}
else return -1;
}
邻接矩阵转邻接表
矩阵为G1,表为G2
void Mtx_to_List(Adj &G1,ADj &G2)
{
G2.vnum=G1.vum;
G2.Enum=G1.Enum;
G2.Vlist=new VNode[MaxNum];
Enode *p,*rear;
for(int i=0;i<G1.vnum;i++)
{
G2.Vlist[i].data=G1.Vlist[i];
G2.Vlist[i].adj=NULL;
for(int j=0;j<G1.vnum;j++)
{//找第一个邻接顶点
if(G1.edge[i][j]) break;
}
if(j<G1.vnum)
{
p=new Enode;
p->dest=j;//插入新的边结点
p->link=G2.Vlist[i].adj;
G2.Vlist[i].adj=p;
rear=p;
for(int j+1;k<G1.vnum;k++)
{//找下一个邻接顶点
if(G1.edge[i][k])
{
p=Enode;//插入新的边结点
p->dest=k;
p->link=rear->link;
rear->link=p;//插入链尾
rear=p;
}
}
}
}
}
邻接表转邻接矩阵
表为G1,矩阵为G2
void List_to_Mtx(ADj &G1,Adj &G2)
{
G2.vnum=G1.vum;
G2.Enum=G1.Enum;
Enode *p;
G2.Vlist=new VNode[MaxNum];
G2.edge=new *weight[MaxNum];
for(int i=0;i<MaxNum;i++)
{
G2.edge[i]=new *weight[MaxNum];
for(int i=0;i<MaxNum;i++)
{
for(int j=0;j<MaxNum;j++)
{
G2.edge[i][j]=0;
}
}
for(int i=0;i<MaxNum;i++)
{
G2.Vlist[i]=G1.Vlist[i].data;
for(p=G1.Vlist[i].adj;p!=NULL;p=p->link)
{
G2.edge[i][p->dest]=1;
}
}