图的存储结构,包括:邻接矩阵、邻接表、十字链表、邻接多重表
其中邻接表和邻接矩阵是图的两种常用存储表示方式,用于记录图中任意两个顶点之间的连通关系,包括权值。
1.邻接矩阵
#include<stdio.h>
#include<stdlib.h>
#define MAXINT 32767
#define MVNum 100
#define OK 1
#define ERROR 0
typedef int Status;
typedef char VerTextType;//定义顶点数据类型全为char型
typedef int ArcType;//定义边的权值为整型
typedef struct{
VerTextType vexs[MVNum];//顶点表
ArcType arcs[MVNum][MVNum];//邻接矩阵
int vexnum, arcnum;//顶点数和路径数
}AMGraph;
int LocateVex(AMGraph G, VerTextType u){
//存在则返回u在顶点表中的下标,否则返回-1
for(int i = 0;i<G.vexnum; i++)
{
if(u==G.vexs[i]) return i;
}
return -1;
}
//采用邻接矩阵表示法,创建无线网(UDN算法)
Status CreatUDN(AMGraph &G){
VerTextType v1, v2;//定义顶点
ArcType w;//定义权重(只能为0或1)
printf("请输入顶点数和边数: \n");
scanf("%d %d",&G.vexnum,&G.arcnum);//输入邻接矩阵的顶点数和路径数
getchar();
printf("请输入顶点: \n");
for(int i = 0; i < G.vexnum; i++){
scanf("%c", &G.vexs[i]);
} //off for i.
getchar();
for(int i = 0;i < G.vexnum; i++){
for(int j = 0; j<G.vexnum; j++){
G.arcs[i][j] = MAXINT;//初始化矩阵中的每一个位置为最大值
}//off for j.
}//off for i.
printf("请输入边的两个顶点及权重: \n");
for(int k = 0; k<G.arcnum; k++){
scanf("%c %c %d",&v1, &v2, &w);//输入一条边的顶点和权重.
getchar();
int i = LocateVex(G,v1);
int j = LocateVex(G,v2);//确定v1,v2在邻接矩阵中的位置
G.arcs[i][j] = w;
G.arcs[j][i]=G.arcs[i][j];
}
return OK;
}//off creatUDN
void printGraph(AMGraph G){
int i, j;
for(i = 0;i<G.vexnum; i++)
{
for(j = 0; j<G.vexnum;j++)
{
printf("%-5d ",G.arcs[i][j]);
if(j==G.vexnum-1) printf("\t\n");
}
}
}
//Entrance
int main(){
AMGraph G;
CreatUDN(G);
printGraph(G);
return 0;
}
2.邻接表
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
/*data:数据域,存储顶点信息
firstarc:指针域,指向边表中的第一个节点
adjvex:邻接点域
nextarc:指针域,指向边表的下一结点
info:存储和边或狐有关的信息,如权值
vex:顶点
arc:边*/
#define OK 1
#define ERROR 0
#define MVnum 100
typedef char VexTextType;//定义顶点数据类型全为char型
typedef int InfoType;//定义其他信息为int型,如权值等
typedef int Status;
//定义邻接表
//定义边表
typedef struct ArcNode{
int adjvex;//该边所指的顶点位置
struct ArcNode *nextarc;//指向下一条边的指针
InfoType info;//该边的相关信息
}ArcNode;
//定义顶点表
typedef struct VNode{
VexTextType data;//顶点信息
ArcNode *firstarc;//指向第一条依附该顶点的边的指针
}VNode, AdjList[MVnum];//AdjList表示邻接表类型
//图
typedef struct{
AdjList vertices;//邻接表 vertices[i] = VNode[i].data;
int vexnum, arcnum;//顶点数和边数
}ALGraph;
//Locate
int Locate(ALGraph G, VexTextType u){
//存在则返回u在顶点表中的下标,否则返回-1
for(int i = 0;i<G.vexnum; i++)
{
if(u==G.vertices[i].data)
return i;
}
return -1;
}
//图邻接表存储建立算法(UDG)
Status CreatUDG(ALGraph &G){
int v1, v2;
printf("请输入顶点个数和边数: ");
scanf("%d %d",&G.vexnum, &G.arcnum);
printf("请输入顶点: ");
for(int i = 0;i<G.vexnum;i++){ //输入各点,构造表头结点表
scanf("%d",&G.vertices[i].data); //输入顶点值
G.vertices[i].firstarc = NULL;//初始化表头结点指针域为空
}
for(int k = 0;k<G.arcnum;k++){
printf("请输入一对连接点: ");
scanf("%d %d",&v1,&v2);
int i = Locate(G,v1);
int j = Locate(G,v2);
ArcNode *p1 = (ArcNode *)malloc(sizeof(ArcNode));
p1->adjvex = j;//邻接点序号为j
p1->nextarc = G.vertices[i].firstarc;
G.vertices[i].firstarc = p1;//将新节点p1插入顶点vi的边表头部
ArcNode *p2 = (ArcNode *)malloc(sizeof(ArcNode));
p2->adjvex = i;//邻接点序号为i
p2->nextarc = G.vertices[j].firstarc;
G.vertices[j].firstarc = p2;//将新节点p2插入顶点vj的边表头部
}
return OK;
}
void printGraph(ALGraph G){
ArcNode *p;
for(int i = 0;i<G.vexnum;i++){
printf("%d->",G.vertices[i].data);
p = G.vertices[i].firstarc;
while(p){
printf("%d->",G.vertices[p->adjvex].data);
p = p->nextarc;
}
if (p==NULL)
printf("NULL\n");
}
}
int main(){
ALGraph G;
CreatUDG(G);
printGraph(G);
return 0;
}