图的存储结构(邻接矩阵)

一、邻接矩阵(无向图):

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");
}

猜你喜欢

转载自blog.csdn.net/weixin_42617472/article/details/84592866