一、邻接表存储类型
/*-----------边的定义-------------*/
typedef struct ENode *PtrToENode;
struct ENode{
Vertex V1,V2;//有向边<V1,V2>
WeightType Weight; //权值
};
typedef PtrToENode Edge;
/*-----------邻接点的定义-------------*/
typedef struct AdjVNode *PtrToAdjVNode;
struct AdjVNode{
Vertex AdjV;//邻接点下标
WeightType Weight;//边的权值
PtrToAdjVNode Next;//指向下一个邻接点
};
/*-----------顶点表头结点的定义-------------*/
typedef struct VNode{
PtrToAdjVNode FirstEdge;//边表头指针
DataType Data;//存顶点的数据
}AdjList[MaxVertexNum];//AdjList是邻接表类型
/*-----------图结点的定义-------------*/
typedef struct GNode *PtrToGNode;
struct GNode{
int Nv;//顶点数
int Ne;//边数
AdjList G;//邻接表
};
typedef PtrToGNode LGraph;
二、图的初始化
LGraph CreateGraph(int VertexNum)
{
//初始化一个只有顶点没有边的图
LGraph Graph;
Vertex V;
Graph=(LGraph)malloc(sizeof(struct GNode));
Graph->Nv =VertexNum;
Graph->Ne =0;
//初始化邻接表头指针
for(V=0;V<Graph->Nv ;V++)
Graph->G[V].FirstEdge =NULL;
return Graph;
}
三、插入边
void InsertEdge(LGraph Graph,Edge E)
{
//逐条加入边
PtrToAdjVNode NewNode;
//插入边<V1,V2>,为V2建立新的连接点
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;
}
四、完整代码
//邻接表存储的有向图
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#define MaxVertexNum 100 //最大顶点数
typedef int Vertex; //用顶点下标表示顶点,为整型
typedef int WeightType; //边的权值设为整型
typedef char DataType; //顶点存储的数据类型为字符型
/*-----------边的定义-------------*/
typedef struct ENode *PtrToENode;
struct ENode{
Vertex V1,V2;//有向边<V1,V2>
WeightType Weight; //权值
};
typedef PtrToENode Edge;
/*-----------邻接点的定义-------------*/
typedef struct AdjVNode *PtrToAdjVNode;
struct AdjVNode{
Vertex AdjV;//邻接点下标
WeightType Weight;//边的权值
PtrToAdjVNode Next;//指向下一个邻接点
};
/*-----------顶点表头结点的定义-------------*/
typedef struct VNode{
PtrToAdjVNode FirstEdge;//边表头指针
DataType Data;//存顶点的数据
}AdjList[MaxVertexNum];//AdjList是邻接表类型
/*-----------图结点的定义-------------*/
typedef struct GNode *PtrToGNode;
struct GNode{
int Nv;//顶点数
int Ne;//边数
AdjList G;//邻接表
};
typedef PtrToGNode LGraph;
/*-----------创建-------------*/
LGraph CreateGraph(int VertexNum)
{
//初始化一个只有顶点没有边的图
LGraph Graph;
Vertex V;
Graph=(LGraph)malloc(sizeof(struct GNode));
Graph->Nv =VertexNum;
Graph->Ne =0;
//初始化邻接表头指针
for(V=0;V<Graph->Nv ;V++)
Graph->G[V].FirstEdge =NULL;
return Graph;
}
/*-----------插入-------------*/
void InsertEdge(LGraph Graph,Edge E)
{
//逐条加入边
PtrToAdjVNode NewNode;
//插入边<V1,V2>,为V2建立新的连接点
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;
}
/*-----------创建-------------*/
LGraph BuildGraph()
{
LGraph Graph;
Vertex V;
Edge E;
int Nv,i;
printf("请输入图的的顶点数:");
scanf("%d",&Nv);
Graph=CreateGraph(Nv);
printf("请输入边的个数:");
scanf("%d",&(Graph->Ne ));
if(Graph->Ne !=0){//有边
E=(Edge)malloc(sizeof(struct ENode));
printf("请输入%d个边的起点 终点 权值:\n",Graph->Ne );
for(i=0;i<Graph->Ne ;i++){
printf("第%d条边:",i+1);
scanf("%d %d %d",&E->V1 ,&E->V2 ,&E->Weight );
InsertEdge(Graph,E);
}
}
//如果顶点有数据的话,读入数据
// for(V=0;V<Graph->Nv ;V++)
// scanf("%c",&(Graph->G[V].Data ));
return Graph;
}
void PrintResult(LGraph Graph)
{
Vertex V;
for(V=0;V<Graph->Nv ;V++){
printf("%d : ",V);
while(Graph->G[V].FirstEdge){
printf("%d ",Graph->G[V].FirstEdge->AdjV );
Graph->G[V].FirstEdge=Graph->G[V].FirstEdge->Next ;
}
printf("\n");
}
}
int main()
{
LGraph Graph;
Graph=BuildGraph();
PrintResult(Graph);
return 0;
}
五、运行
注意:本代码没有输入顶点的数据,需要顶点数据可以将注释删除,读入顶点数据
有向图:
无向图: