一、邻接矩阵(无向图):
1、图的邻接矩阵(Adjacency Matrix)存储方式是用两个数组来表示图。一个一维数组存储图中顶点信息,一个二维数组(称为邻接矩阵)存储图中的边或弧的信息。
2、我们可以设置两个数组,顶点数组为vertex[4]={V0,V1,V2,V3},边数组arc[4][4]为对称矩阵(0表示不存在顶点间的边,1表示顶点间存在边)。
3、对称矩阵:所谓对称矩阵就是n阶矩阵的元满足a[i][j]=a[j][i](0<=i,j<=n)。即从矩阵的左上角到右下角的主对角线为轴,右上角的元与左下角相对应的元全都是相等的。
4、有了这个二维数组组成的对称矩阵,我们就可以很容易地知道图中的信息:
--要判定任意两顶点是否有边无边就非常容易了;
--要知道某个顶点的度,其实就是这个顶点Vi在邻接矩阵中第i行(或第i列)的元素之和;
--求顶点Vi的所有邻接点就是将矩阵中第i行元素扫描一遍,arc[i][j]为1就是邻接点。
代码:
//无向图邻接矩阵
#include<iostream>
using namespace std;
#define VERTEX 4
typedef struct ArrayGraph
{
char VertexArr[VERTEX];//顶点元素矩阵
int EdgeArr[VERTEX][VERTEX];//边矩阵二维数组
}ArrayGraph;
void ArrayGraph_init(ArrayGraph *T);//初始化图
void ArrayGraph_create(ArrayGraph *T);//创建图
void ArrayGraph_show(ArrayGraph *T);
int main()
{
ArrayGraph T;
ArrayGraph_init(&T);
ArrayGraph_create(&T);
ArrayGraph_show(&T);
return 0;
}
//先对边矩阵进行初始化,因为在无向图的边矩阵中,对角线上都为0
void ArrayGraph_init(ArrayGraph *T)
{
int i;
for(i=0;i<VERTEX;i++)
{
T->EdgeArr[i][i]=0;
}
}
//创建一个图
void ArrayGraph_create(ArrayGraph *T)
{
//输入顶点元素,对顶点数据进行初始化
for(int i=0;i<VERTEX;i++)
{
printf("请输入第%d个顶点值:",i+1);
scanf("%c",&(T->VertexArr[i]));
getchar();
}
//填充边关系
for (int j = 0; j <VERTEX; ++j) //填充边关系
{
for (int i = j+1; i < VERTEX; ++i)
{
printf("若元素%c和%c有边,则输入1,否则输入0\t",T->VertexArr[j],T->VertexArr[i]);
scanf("%d",&( T->EdgeArr[j][i]));
T->EdgeArr[i][j] = T->EdgeArr[j][i]; //对称
}
}
}
void ArrayGraph_show(ArrayGraph *T)//显示图
{
printf("顶点元素如下:\n");
for(int i=0;i<VERTEX;i++)
{
printf("%5c",T->VertexArr[i]);
}
printf("\n边矩阵如下:\n ");
for(int i=0;i<VERTEX;++i)
{
printf("%4c",T->VertexArr[i]);
}
printf("\n");
for(int i=0;i<VERTEX;i++)
{
printf("%c",T->VertexArr[i]);
for(int j=0;j<VERTEX;j++)
{
printf("%4d",T->EdgeArr[i][j]);
}
printf("\n");
}
printf("\n");
}
二、邻接矩阵(有向图):
1、顶点数组vertex[4]={V0,V1,V2,V3},弧数组arc[4][4]也是一个矩阵,但因为是有向图,所以这个矩阵并不对称,例如由V1到V0有弧,得到arc[1][0]=1,而V0到V1没有弧,因此arc[0][1]=0。
2、有向图要考虑入度和出度,顶点V1的入度为1,正好是第V1列的各数之和,顶点V1的出度为2,正好是第V1行的各数之和。
代码:
//有向图邻接矩阵
#include<iostream>
using namespace std;
#define VERTEX 4
typedef struct ArrayGraph
{
char VertexArr[VERTEX];
int EdgeArr[VERTEX][VERTEX];
}ArrayGraph;
void ArrayGraph_init(ArrayGraph *T);
void ArrayGraph_create(ArrayGraph *T);
void ArrayGraph_show(ArrayGraph *T);
int main()
{
ArrayGraph T;
ArrayGraph_init(&T);
ArrayGraph_create(&T);
ArrayGraph_show(&T);
return 0;
}
//对边矩阵进行初始化
void ArrayGraph_init(ArrayGraph *T)
{
for(int i=0;i<VERTEX;i++)
{
T->EdgeArr[i][i]=0;
}
}
//创建图
void ArrayGraph_create(ArrayGraph *T)
{
//输入顶点元素,对顶点元素进行初始化
for(int i=0;i<VERTEX;i++)
{
printf("请输入第%d个顶点值:",i+1);
scanf("%c",&T->VertexArr[i]);
getchar();
}
//对边矩阵进行初始化
for(int i=0;i<VERTEX;i++)
{
for(int j=i+1;j<VERTEX;j++)
{
printf("若元素%c指向%c,则输入1,否则为0。",T->VertexArr[i],T->VertexArr[j]);
scanf("%d",&T->EdgeArr[i][j]);
printf("若元素%c指向%c,则输入1,否则为0。",T->VertexArr[j],T->VertexArr[i]);
scanf("%d",&T->EdgeArr[j][i]);
}
}
}
void ArrayGraph_show(ArrayGraph *T)
{
printf("顶点元素如下:\n");
for(int i=0;i<VERTEX;i++)
{
printf("%4c",T->VertexArr[i]);
}
printf("\n边矩阵如下:\n ");
for(int i=0;i<VERTEX;i++)
{
printf("%4c",T->VertexArr[i]);
}
printf("\n");
for(int i=0;i<VERTEX;i++)
{
printf("%c",T->VertexArr[i]);
for(int j=0;j<VERTEX;j++)
{
printf("%4d",T->EdgeArr[i][j]);
}
printf("\n");
}
}
三、邻接矩阵(网):
1、每条边上带有权的图就叫网。
这里“∞”表示一个计算机允许的、大于所有边上权值的值。
代码:
//有权值无向图邻接矩阵
#include<iostream>
using namespace std;
#define VERTEX 4
#define INFINITY 65535
typedef struct ArrayNet
{
char VertexArr[VERTEX];
int EdgeArr[VERTEX][VERTEX];
}ArrayNet;
void ArrayNet_init(ArrayNet *T);
void ArrayNet_create(ArrayNet *T);
void ArrayNet_show(ArrayNet *T);
int main()
{
ArrayNet T;
ArrayNet_init(&T);
ArrayNet_create(&T);
ArrayNet_show(&T);
return 0;
}
void ArrayNet_init(ArrayNet *T)
{
for(int i=0;i<VERTEX;i++)
{
T->EdgeArr[i][i]=65535;
}
}
void ArrayNet_create(ArrayNet *T)
{
for(int i=0;i<VERTEX;i++)
{
printf("请输入第%d个顶点值:",i+1);
scanf("%c",&T->VertexArr[i]);
getchar();
}
for(int i=0;i<VERTEX;i++)
{
for(int j=i+1;j<VERTEX;j++)
{
printf("输入顶点%c与顶点%c的权值,如果没有权值则输入65535。",T->VertexArr[i],
T->VertexArr[j]);
scanf("%d",&T->EdgeArr[i][j]);
T->EdgeArr[j][i]=T->EdgeArr[i][j];
}
}
}
void ArrayNet_show(ArrayNet*T)//显示图
{
printf("顶点元素如下:\n");
for(int i=0;i<VERTEX;i++)
{
printf("%8c",T->VertexArr[i]);
}
printf("\n边矩阵如下:\n ");
for(int i=0;i<VERTEX;++i)
{
printf("%8c",T->VertexArr[i]);
}
printf("\n");
for(int i=0;i<VERTEX;i++)
{
printf("%-8c",T->VertexArr[i]);
for(int j=0;j<VERTEX;j++)
{
if(T->EdgeArr[i][j]==65535)
{
printf("∞ ");
}
else
{
printf("%-8d",T->EdgeArr[i][j]);
}
}
printf("\n");
}
printf("\n");
}
//有权值有向图邻接矩阵
#include<iostream>
using namespace std;
#define VERTEX 4
#define INFINITY 65535
typedef struct ArrayNet
{
char VertexArr[VERTEX];
int EdgeArr[VERTEX][VERTEX];
}ArrayNet;
void ArrayNet_init(ArrayNet *T);
void ArrayNet_create(ArrayNet *T);
void ArrayNet_show(ArrayNet *T);
int main()
{
ArrayNet T;
ArrayNet_init(&T);
ArrayNet_create(&T);
ArrayNet_show(&T);
return 0;
}
//对边矩阵进行初始化
void ArrayNet_init(ArrayNet *T)
{
for(int i=0;i<VERTEX;i++)
{
T->EdgeArr[i][i]=65535;
}
}
//创建图
void ArrayNet_create(ArrayNet *T)
{
//输入顶点元素,对顶点元素进行初始化
for(int i=0;i<VERTEX;i++)
{
printf("请输入第%d个顶点值:",i+1);
scanf("%c",&T->VertexArr[i]);
getchar();
}
//对边矩阵进行初始化
for(int i=0;i<VERTEX;i++)
{
for(int j=i+1;j<VERTEX;j++)
{
printf("若元素%c指向%c,则输入权值,否则输入65535。",T->VertexArr[i],T->VertexArr[j]);
scanf("%d",&T->EdgeArr[i][j]);
printf("若元素%c指向%c,则输入权值,否则输入65535。",T->VertexArr[j],T->VertexArr[i]);
scanf("%d",&T->EdgeArr[j][i]);
}
}
}
void ArrayNet_show(ArrayNet*T)//显示图
{
printf("顶点元素如下:\n");
for(int i=0;i<VERTEX;i++)
{
printf("%8c",T->VertexArr[i]);
}
printf("\n边矩阵如下:\n ");
for(int i=0;i<VERTEX;++i)
{
printf("%8c",T->VertexArr[i]);
}
printf("\n");
for(int i=0;i<VERTEX;i++)
{
printf("%-8c",T->VertexArr[i]);
for(int j=0;j<VERTEX;j++)
{
if(T->EdgeArr[i][j]==65535)
{
printf("∞ ");
}
else
{
printf("%-8d",T->EdgeArr[i][j]);
}
}
printf("\n");
}
printf("\n");
}