边节点数据结构:iver,ilink,jver,jlink
创建边节点时,查找iver,jver对应下标开始最后ilink,jlink为空时,把ilink或jlink指向当前所创建的节点。
顶点的edgefrist指针为空时表示创建的边节点为该顶点的第一条边。edgefirst直接指向该节点。
structfun.h
//数据结构函数头文件
#include
#include
#include
using std::cout;
using std::cin;
using std::string;
#define MAXSIZE 100
#define OK 1
#define ERROR 0
#define INFINITY 65535//无穷大
typedef string ElemType;
typedef string VertexType;//图顶点数据类型
typedef int EdgeType;//图边的数据类型
//数据结构-图-----------------------------------------------------------------------------
//1、邻接矩阵(Adjacency Martix)
//设置一个顶点数组vertex[],设置一个边数组arc[][]
typedef struct
{
//图顶点数组
VertexType vertex[MAXSIZE];
//图边数组
EdgeType arc[MAXSIZE][MAXSIZE];
int vertexnum,arcnum;
}AdjMarGraph;
//2、邻接表(Adjacency List)
//设置一个顶点数组vertex[],设置一个边的链表,顶点的next指向所对应的链表
typedef struct EdgeNode//边链表节点
{
EdgeType arcVertex;
int weight;//权值
EdgeNode *next;
}EdgeNode;
typedef struct//顶点数组
{
VertexType vertex;
EdgeNode *firstEdge;
}VertexList[MAXSIZE];
typedef struct//图结构
{
VertexList vlist;
int numVertex,numArc;
}AdjListGraph;
//3、十字链表(Orthogonal->正交的 List)
//设置一个顶点数组vertex[],设置一个边的链表,顶点的next指向所对应的链表
//链表节点 tailvex headvex headlink,taillink; 改成invex,outvex,outlink,inlink更好理解
//入顶点,出顶点,出链接,入链接
typedef struct OrthogonalLinkNode
{
EdgeType invex,outvex;
OrthogonalLinkNode *outlink,*inlink;
int weight;//边的权重
}OrthogonalLinkNode;
//数组顶点节点 vertex 顶点 edgein 入边 edgeout 出边
typedef struct
{
VertexType vertex;
OrthogonalLinkNode *edgein,*edgeout;
}OrthogonalEdgeNode[MAXSIZE];
//十字链表结构
typedef struct
{
OrthogonalEdgeNode vertexlist;
int numvertex,numedge;
}OrthogonalListGraph;
//4、无向图 邻接多重表结构Adjacency Multiple Table(邻接多重表就是一个顶点的多条边用链表链接)
//ivex ilink jvex jlink (ivex jvex 边的两个顶点,ilink指向值与ivex相同的jvex的节点,jlink指向值与jvex相同的下一个节点。
typedef struct AMTEdgeNode//边链表节点
{
EdgeType iver,jver;
int weight;//权值
AMTEdgeNode *ilink,*jlink;
}AMTEdgeNode;
typedef struct//顶点数组
{
VertexType vertex;
AMTEdgeNode *firstEdge;
}AMTVertexList[MAXSIZE];
typedef struct//图结构
{
AMTVertexList vlist;
int numVertex,numArc;
}AdjacencyMultipleTableGraph;
//1、邻接矩阵
//无向图的邻接矩阵
int CreateAdjMaxGraph(AdjMarGraph *amg);
//2、邻接表
int CreateAdjListGraph(AdjListGraph *alg);
//3、十字链表
int CreateOrthogonalListGraph(OrthogonalListGraph *olg);
//4、邻接多重表结构
int CreateAdjacencyMultipleTableGraph(AdjacencyMultipleTableGraph *amtg);
structfun.cpp
#include
#include
#include
#include
#include"structfun.h"
using std::cout;
using std::cin;
using std::string;
using std::endl;
using std::ostringstream;
//图结构函数-----------------------------------------------
//1、邻接矩阵
//图的邻接矩阵
int CreateAdjMaxGraph(AdjMarGraph *amg)
{
int i=0;
amg->vertexnum=0;
amg->arcnum=0;
while(1)//输入顶点;
{
printf("请输入顶点,结束用#号:");
/* scanf("%s",&amg->vertex[i]);*///string不能采用scanf,采用scanf必须先给字符串
//预先分配空间,然后采用amg->vertex[i][0]scanf采用的是字符数组的形式存储字符串。
//amg->vertex[i].resize(100);
//scanf("%s",&amg->vertex[i][0]);
cin>>amg->vertex[i];
if(amg->vertex[i]=="#")
break;
amg->vertexnum++;
i++;
}
for(i=0;i<amg->vertexnum;i++)//初始化边值为0
for(int j=0;j<amg->vertexnum;j++)
{
if(i==j)
amg->arc[i][j]=0;
else
amg->arc[i][j]=INFINITY;
}
//创建邻接矩阵图的边
while(1)
{
int v1,v2,value;
printf("请输入图的边的顶点下标(v1,v2,value)结束输入(0,0,0):");
scanf("%d,%d,%d",&v1,&v2,&value);
amg->arc[v1][v2]=value;
/*amg->arc[v2][v1]=value;*///无向图增加对等矩阵另外一边的值
if(!v1&!v2&!value)
break;
amg->arcnum++;
}
//输出图的邻接矩阵
printf("图的邻接矩阵:\n");
for(i=0;i<amg->vertexnum;i++)
{
printf("%s: ",amg->vertex[i].c_str());
for(int j=0;j<amg->vertexnum;j++)
{
printf("%d ",amg->arc[i][j]);
if(j==amg->vertexnum-1)
printf("\n");
}
}
return OK;
}
//2、邻接表
int CreateAdjListGraph(AdjListGraph *alg)
{
int i=0;
alg->numVertex=0;
alg->numArc=0;
while(1)//创建顶点
{
printf("请输入邻接表的顶点结束用#:");
cin>>alg->vlist[i].vertex;
if(alg->vlist[i].vertex=="#")
break;
alg->vlist[i].firstEdge=NULL;
i++;
alg->numVertex++;
}
while(1)//创建边链表
{
int v1=0,v2=0,w=0;
EdgeNode *edgenode;
printf("请输入邻接表的顶点对应的边(v1,v2,w)以(0,0,0)结束:");
scanf("%d,%d,%d",&v1,&v2,&w);
if(!v1&&!v2&&!w)//(0,0,0)结束
break;
edgenode = new EdgeNode();//创建边节点
edgenode->arcVertex=v2;
edgenode->weight=w;
edgenode->next=NULL;
if(alg->vlist[v1].firstEdge==NULL)//插入边节点
alg->vlist[v1].firstEdge=edgenode;
else
{
EdgeNode *temp;
temp=alg->vlist[v1].firstEdge;
while(temp->next!=NULL)
temp=temp->next;
temp->next=edgenode;
}
alg->numArc++;
}
return OK;
}
//3、十字链表(就是邻接表与逆邻接表合并)好处是方便同时具有图的出边和入边
int CreateOrthogonalListGraph(OrthogonalListGraph *olg)
{
int i=0;
olg->numvertex=0;
olg->numedge=0;
while(1)//输入顶点
{
printf("请输入图的顶点(以#结束):");
cin>>olg->vertexlist[i].vertex;
if(olg->vertexlist[i].vertex=="#")
break;
olg->numvertex++;
olg->vertexlist[i].edgein=NULL;
olg->vertexlist[i].edgeout=NULL;
i++;
}
while(1)//输入图的边
{
OrthogonalLinkNode *edge;
edge=new OrthogonalLinkNode();
edge->inlink=NULL;
edge->outlink=NULL;
int v1=0,v2=0,w=0;
printf("请输入图的有向边(v1,v2,w)(0,0,0)结束:");
scanf("%d,%d,%d",&v1,&v2,&w);
if(!v1&&!v2&&!w)
break;
edge->outvex=v2;
edge->invex=v1;//这一步是逆矩阵合并的步骤--edge->invex都等于链表的头顶点
if(olg->vertexlist[v1].edgeout==NULL)
{
olg->vertexlist[v1].edgeout=edge;
}else
{
OrthogonalLinkNode *temp;
temp=new OrthogonalLinkNode();
temp=olg->vertexlist[v1].edgeout;
while(temp->outlink)
temp=temp->outlink;
temp->outlink=edge;
}
//最后处理图的入边与邻接表相比多了这个步骤,这个步骤是把逆邻接表串联起来,开头位置是edgein
if(olg->vertexlist[v2].edgein==NULL)
olg->vertexlist[v2].edgein=edge;
else
{
OrthogonalLinkNode *temp;
temp=new OrthogonalLinkNode();
temp=olg->vertexlist[v2].edgein;
while(temp->inlink)
temp=temp->inlink;
temp->inlink=edge;
}
}
return OK;
}
//4、邻接多重表结构
int CreateAdjacencyMultipleTableGraph(AdjacencyMultipleTableGraph *amtg)
{
int i=0;
amtg->numVertex=0;
amtg->numArc=0;
while(1)//创建顶点
{
printf("请输入邻接表的顶点结束用#:");
cin>>amtg->vlist[i].vertex;
if(amtg->vlist[i].vertex=="#")
break;
amtg->vlist[i].firstEdge=NULL;
i++;
amtg->numVertex++;
}
while(1)//创建边
{
int v1,v2,w;
AMTEdgeNode *node,*temp;
node=new AMTEdgeNode();
printf("请输入的边(v1,v2,w)用(0,0,0)结束:");
scanf("%d,%d,%d",&v1,&v2,&w);
if(!v1&&!v2&&!w)//(0,0,0)结束
break;
node->iver=v1;
node->jver=v2;
node->weight=w;
node->ilink=NULL;
node->jlink=NULL;
if(!amtg->vlist[v1].firstEdge)//列表的firstEdge为空则指向节点
amtg->vlist[v1].firstEdge=node;
if(!amtg->vlist[v2].firstEdge)//列表的firstEdge为空则指向节点
amtg->vlist[v2].firstEdge=node;
if(amtg->vlist[v1].firstEdge!=node)
{
temp=new AMTEdgeNode();//处理v1的ilink和jlink
temp=amtg->vlist[v1].firstEdge;
while(temp)
{
if(temp->iver==v1)
{
if(!temp->ilink)//沿着链表找到ilink的最后为空,此时指针可以指向node
{
temp->ilink=node;
break;
}
temp=temp->ilink;//否则继续下一个ilink节点
}
else
{
if(!temp->jlink&&temp->jver==v1)
{
temp->jlink=node;
break;
}
temp=temp->jlink;
}
}
}
if(amtg->vlist[v2].firstEdge!=node)
{
temp=new AMTEdgeNode();//处理v2的ilink和jlink
temp=amtg->vlist[v2].firstEdge;
while(temp)
{
if(temp->iver==v2)
{
if(!temp->ilink)
{
temp->ilink=node;
break;
}
temp=temp->ilink;
}
else
{
if(!temp->jlink&&temp->jver==v2)
{
temp->jlink=node;
break;
}
temp=temp->jlink;
}
}
}
amtg->numArc++;
}
return OK;
}
main.cpp
#include
#include
#include
#include
#include"structfun.h"
using std::string;
using std::printf;
using std::scanf;
using std::endl;
using std::to_string;
void main()
{
//图的邻接矩阵
//AdjMarGraph amg;
//CreateAdjMaxGraph(&amg);
//图的邻接表
//AdjListGraph alg;
//CreateAdjListGraph(&alg);
//图的十字链表
//OrthogonalListGraph olg;
//CreateOrthogonalListGraph(&olg);
//图的邻接多重表
AdjacencyMultipleTableGraph amtg;
CreateAdjacencyMultipleTableGraph(&amtg);
system("pause");
}