数据结构(C实现)------- 图的邻接矩阵表示
2015-01-07 00:02
351 查看
[本文是自己学习所做笔记,欢迎转载,但请注明出处:http://blog.csdn.net/jesson20121020]
邻接矩阵是表示顶点之间相邻顶点之间相邻关系的矩阵。设G=(V,E)是具有n个顶点的图,若(vi,vj)属于E,则对应G的邻接矩阵中的元素A[i][j]
= wij 或1,否则,A[i][j] = 0或无穷大,其中,wij可以指边的权重。
无向图或无向网的邻接矩阵一定是对称的,因为当(vi,vj)属于E时,也有(vj,vi)属于E。而有向图或有向网的邻接矩阵不一定对称,所以用邻接矩阵表示一个有n个顶点的有向图或有向网时,所需的存储空间为n^2。由于无向图或无向网的邻接矩阵是对称的,因此可采用压缩存储的方法,仅存储下三角矩阵(包括主对角线上的元素)中的元素,存储空间只需n*(n+1)/2。显然,邻接矩阵表示法的空间复杂度为s(n)
= O(n^2)。
用邻接矩阵表示图,除了存储用于表示顶点间相邻关系的邻接矩阵外,通常还需要一个一维数组存储顶点信息。设计如下:
建立图的邻接矩阵的算法描述如下:
(1) 输入图的类型(无向图还是有向图)
(2) 输入图的顶点数,边数
(3) 输入顶点的字符信息,建立顶点数组
(4) 初始化邻接矩阵
(5) 输入边的信息,建立图的邻接矩阵,注意区分是图的类型,另外,如果是有权图,邻接矩阵保存其边的权重,这里是无权图。
算法源代码如下:
该算法的时间复杂度为O(n^2+n*e),其中O(n^2)的时间耗费在邻接矩阵的初始化操作上,O(n*e)的时间耗费在邻接矩阵的建立操作上,因为在一般情况下,e<<n^2,所以,该算法的时间复杂度为O(n^2)。
完整代码如下:
执行结果:
邻接矩阵是表示顶点之间相邻顶点之间相邻关系的矩阵。设G=(V,E)是具有n个顶点的图,若(vi,vj)属于E,则对应G的邻接矩阵中的元素A[i][j]
= wij 或1,否则,A[i][j] = 0或无穷大,其中,wij可以指边的权重。
无向图或无向网的邻接矩阵一定是对称的,因为当(vi,vj)属于E时,也有(vj,vi)属于E。而有向图或有向网的邻接矩阵不一定对称,所以用邻接矩阵表示一个有n个顶点的有向图或有向网时,所需的存储空间为n^2。由于无向图或无向网的邻接矩阵是对称的,因此可采用压缩存储的方法,仅存储下三角矩阵(包括主对角线上的元素)中的元素,存储空间只需n*(n+1)/2。显然,邻接矩阵表示法的空间复杂度为s(n)
= O(n^2)。
用邻接矩阵表示图,除了存储用于表示顶点间相邻关系的邻接矩阵外,通常还需要一个一维数组存储顶点信息。设计如下:
#define MAX_VEX_NUM 50 typedef char VertexType; typedef enum { DG, UDG } GraphType; typedef struct { VertexType vexs[MAX_VEX_NUM]; int arcs[MAX_VEX_NUM][MAX_VEX_NUM]; int vexnum, arcnum; GraphType type; } MGraph;
建立图的邻接矩阵的算法描述如下:
(1) 输入图的类型(无向图还是有向图)
(2) 输入图的顶点数,边数
(3) 输入顶点的字符信息,建立顶点数组
(4) 初始化邻接矩阵
(5) 输入边的信息,建立图的邻接矩阵,注意区分是图的类型,另外,如果是有权图,邻接矩阵保存其边的权重,这里是无权图。
算法源代码如下:
void create_MG(MGraph *MG) { int i, j, k; int v1, v2, type; char c1, c2; printf("Please input graph type DG(0) or UDG(1) :"); scanf("%d", &type); if (type == 0) MG->type = DG; else if (type == 1) MG->type = UDG; else { printf("Please input correct graph type DG(0) or UDG(1)!"); return; } printf("Please input vexmun : "); scanf("%d", &MG->vexnum); printf("Please input arcnum : "); scanf("%d", &MG->arcnum); getchar(); for (i = 1; i <= MG->vexnum; i++) { printf("Please input %dth vex(char):", i); scanf("%c", &MG->vexs[i]); getchar(); } //初始化邻接矩阵 for (i = 1; i <= MG->vexnum; i++) { for (j = 1; j <= MG->vexnum; j++) { MG->arcs[i][j] = 0; } } //输入边的信息,建立邻接矩阵 for (k = 1; k <= MG->arcnum; k++) { printf("Please input %dth arc v1(char) v2(char) : ", k); scanf("%c %c", &c1, &c2); v1 = getIndexOfVexs(c1, MG); v2 = getIndexOfVexs(c2, MG); if (MG->type上 == 1) MG->arcs[v1][v2] = MG->arcs[v2][v1] = 1; else MG->arcs[v1][v2] = 1; getchar(); } }算法说明:
该算法的时间复杂度为O(n^2+n*e),其中O(n^2)的时间耗费在邻接矩阵的初始化操作上,O(n*e)的时间耗费在邻接矩阵的建立操作上,因为在一般情况下,e<<n^2,所以,该算法的时间复杂度为O(n^2)。
完整代码如下:
/*
============================================================================
Name : Graph.c
Author : jesson20121020
Version : 1.0
Description : create Graph using Adjacency Matrix, Ansi-style
============================================================================
*/
#include <stdio.h>
#include <stdlib.h>
#define MAX_VEX_NUM 50 typedef char VertexType; typedef enum { DG, UDG } GraphType; typedef struct { VertexType vexs[MAX_VEX_NUM]; int arcs[MAX_VEX_NUM][MAX_VEX_NUM]; int vexnum, arcnum; GraphType type; } MGraph;
/**
* 根据名称得到指定顶点在顶点集合中的下标
* vex 顶点
* return 如果找到,则返回下标,否则,返回0
*/
int getIndexOfVexs(char vex, MGraph *MG) {
int i;
for (i = 1; i <= MG->vexnum; i++) {
if (MG->vexs[i] == vex) {
return i;
}
}
return 0;
}
/**
* 创建邻接矩阵
*/
void create_MG(MGraph *MG) {
int i, j, k;
int v1, v2, type;
char c1, c2;
printf("Please input graph type DG(0) or UDG(1) :");
scanf("%d", &type);
if (type == 0)
MG->type = DG;
else if (type == 1)
MG->type = UDG;
else {
printf("Please input correct graph type DG(0) or UDG(1)!");
return;
}
printf("Please input vexmun : ");
scanf("%d", &MG->vexnum);
printf("Please input arcnum : ");
scanf("%d", &MG->arcnum);
getchar();
for (i = 1; i <= MG->vexnum; i++) {
printf("Please input %dth vex(char):", i);
scanf("%c", &MG->vexs[i]);
getchar();
}
//初始化邻接矩阵
for (i = 1; i <= MG->vexnum; i++) {
for (j = 1; j <= MG->vexnum; j++) {
MG->arcs[i][j] = 0;
}
}
//输入边的信息,建立邻接矩阵
for (k = 1; k <= MG->arcnum; k++) {
printf("Please input %dth arc v1(char) v2(char) : ", k);
scanf("%c %c", &c1, &c2);
v1 = getIndexOfVexs(c1, MG);
v2 = getIndexOfVexs(c2, MG);
if (MG->type == 1)
MG->arcs[v1][v2] = MG->arcs[v2][v1] = 1;
else
MG->arcs[v1][v2] = 1;
getchar();
}
}
/**
* 打印邻接矩阵和顶点信息
*/
void print_MG(MGraph MG) {
int i, j;
if(MG.type == DG){
printf("Graph type: Direct graph\n");
}
else{
printf("Graph type: Undirect graph\n");
}
printf("Graph vertex number: %d\n",MG.vexnum);
printf("Graph arc number: %d\n",MG.arcnum);
printf("Vertex set:\n ");
for (i = 1; i <= MG.vexnum; i++)
printf("%c\t", MG.vexs[i]);
printf("\nAdjacency Matrix:\n");
for (i = 1; i <= MG.vexnum; i++) {
j = 1;
for (; j < MG.vexnum; j++) {
printf("%d\t", MG.arcs[i][j]);
}
printf("%d\n", MG.arcs[i][j]);
}
}
/**
* 主函数
*/
int main(void) {
MGraph MG;
create_MG(&MG);
print_MG(MG);
return EXIT_SUCCESS;
}
执行结果:
Please input graph type UG(0) or UDG(1) :0 Please input vexmun : 4 Please input arcnum : 4 Please input 1th vex(char):a Please input 2th vex(char):b Please input 3th vex(char):c Please input 4th vex(char):d Please input 1th arc v1(char) v2(char) : a b Please input 2th arc v1(char) v2(char) : a c Please input 3th arc v1(char) v2(char) : a d Please input 4th arc v1(char) v2(char) : b c Graph type: Direct graph Graph vertex number: 4 Graph arc number: 4 vertex set: a b c d Adjacency Matrix: 0 1 1 1 0 0 1 0 0 0 0 0 0 0 0 0以上实现了图的邻接矩阵表示,其实,图还有其他的存储方式,如邻接表,十字链表等
相关文章推荐
- 数据结构——图的数组实现(邻接矩阵表示法)
- 数据结构之---C语言实现图的数组(邻接矩阵)存储表示
- 数据结构(C实现)------- 图的邻接矩阵表示
- 数据结构—线性表的链式表示和实现
- 数据结构(严蔚敏)抽象数据类型Triplet的表示与实现(第一章)
- 数据结构实验四:图的表示和实现
- 数据结构之:线性表的顺序表示和实现
- 数据结构1:线性表的顺序表示和实现
- 数据结构教程 第八课 线性表的链式表示与实现
- 数据结构——求邻接矩阵表示的图的关节点
- 数据结构4:栈的表示和实现
- 数据结构之图用邻接矩阵实现赋值有向图
- 数据结构:图的实现--邻接矩阵
- 数组的顺序存储表示和实现-数据结构
- 线性表的顺序表示和实现 - 数据结构
- 数据结构8:队列的顺序存储结构表示和实现
- 数据结构教程 第二课 抽象数据类型的表示与实现
- 数据结构——求邻接矩阵表示的图的关节点
- 单链表的表示和实现 - 数据结构
- 数据结构之线性表的顺序表示和实现