图是一种抽象的数据结构,对于不同的题,使用不同的表示方法复杂程度是不一样的。
目前普遍的使用方法有:邻接矩阵表示法和邻接表表示图
使用邻接矩阵表示图
若是ģ中的边则为1。
因此在该表示法中最直接的方法为:
定义一个i * j的数组WeightType G [MaxVertexNum] [MaxVertexNum]; //它的大小由点的个数决定
其中WeightType表示的是边的权。
因此,简单直观快速的定义图的方式:
typedef struct GNode *PtrToGNode; struct GNode { int Nv;//记录顶点数 int Ne;//记录边数 WeightType G[MaxvertexNum][MaxvertexNum];//邻接矩阵 DataType Data[MaxvertexNum];//储存顶点数据 }; typedef PtrToGNode MGraph;//存储图的类型
图的建立
初始化一个由VertxeNum个顶点但是没有边的图
MGraph CreateGraph( int VertexNum)
{
Vertex V,W;
//初始化一个没有边的图
MGraph Graph;
Graph = (MGraph)malloc(sizeof(struct GNode));
Graph->Nv = VertexNum;
Graph->Ne = 0;
//因此需要清空数组的所有边权值为0(当然如果是算最小值则需要将边定义为INF)
for (V=0; V<Graph->Nv; V++)
{
for (W=0; W<Graph->Nv; W++)
{
Graph->G[V][W] = 0;
}
}
rerutn Graph;
}
插入边的过程
//从MGraph中插入边
//对于表示边的图表示法
typedef struct ENode *PtrToENode;
struct ENode
{
Vertex V1,V2;//有向边<v1,v2>
//如果是非网络图则 不需要记录权重数据
WeightType Weight;
};
typedef PtrToENode Edge;
void InsertEdge(MGraph Graph,Edge E)
{
//读入ENode的数据
//把边的权重赋予邻接矩阵
Graph->G[E->V1][E->V2]=E->Weight;
//若是无向图,则需要插入两次
Graph->G[E->V2][E->V1]=E->Weight;
}
建立一个完整的MGraph过程
//建立一个完整的MGraph过程
// 输出格式:
// Nv Ne
// V1 V2 Weight
MGraph BuildGraph()
{
int Nv;
MGraph Graph;
scanf("%d",&Nv);//读入定点数
//因为图的初始化工作只需要读入顶点就可以做所以分开读取有好处
Graph = CreateGraph(Nv);
scanf("%d",&(Graph->Ne));
if(Graph->Ne!=0)
{
//声明临时边
Edge E=(Edge)malloc(sizeof(struct ENode));
for(int i=0;i<Graph->Ne;i++)
{
scanf("%d %d %d",&E->V1,&E->V2,&E->Weight);
InsertEdge(Graph,E);
}
}
//读入顶点的数据
for(Vertex V=0;V<Graph->Nv;V++)
{
scanf(" %c",&(Graph->Data[V]));
}
return Graph;
}
以上版本写题很慢。create 、init、 read data操作下面模块就可以完成
//简化版本
int G[MaxvertexNum][MaxvertexNum],Nv,Ne;
void BuildGraph2()
{
int i,j,v1,v2,w;
scanf("%d",&Nv);
//建立
for(i=0;i<Nv;i++)
{
for(j=0;j<Nv;j++)
{
G[i][j]=0;
}
}
scanf("%d",&Ne);
for(i=0;i<Ne;i++)
{
scanf("%d %d %d",&v1,&v2,&w);
G[v1][v2]=w;
G[v2][v1]=w;
}
}
使用邻接表表示法
G[N]为指针数组,对应矩阵的每一行一个链表,只存非0元素
typedef struct AdjVNode *PtrToAdjVNode;
typedef struct GNode2 *PtrToGNode2;
typedef struct Vnode//头节点
{
PtrToAdjVNode FirstEdge;//表示该头节点总是指向头节点的第一条边
//需要存东西则下面
DataType Data;
} AdjList[MaxvertexNum];
typedef PtrToGNode LGraph;
struct AdjVNode{
Vertex AdjV;//邻接点下标
WeightType Weight;//权重
PtrToAdjVNode Next;
};
struct GNode2
{
int Nv;
int Ne;
AdjList G;//邻接表
};
typedef PtrToGNode LGraph;
//LGraph建立图
typedef int Vertex;
LGraph CreateGraph2(int VertexNum)
{
Vertex V,W;
LGraph Graph;
Graph=(LGraph)malloc(sizeof(struct GNode));
Graph->Nv=VertexNum;
Graph->Ne=0;
for(Vertex V=0;V<Graph->Nv;V++)
Graph->G[V].FirstEdge=NULL;
return Graph;
}
//向LGraph中插入边
void InsertEdge(LGraph Graph,Edge E)
{
PtrToAdjVNode NewNode;
NewNode =(PtrToAdjVNode)malloc (sizeof(struct AdjVNode));
NewNode->AdjV=E->v2;
NewNode->Weight=E->Weight;
//将V2插入V1的表头
NewNode->Next=Graph->G[E->V1].FirstEdge;
Graph->G[E->V1].FirstEdge=NewNode;
//对于无向图 还需插入<v2,v1>
NewNode =(PtrToAdjVNode)malloc(sizeof(struct AdjVNode));
NewNode->AdjV=E->V1;
NewNode->Weight=E->Weight;
//将V1插入V2表头
NewNode->Next=Graph->G[E->V2].FirstEdge;
Graph->G[E->V2].FirstEdge=NewNode;
}