第七章 图《大话数据结构》读后笔记
图的定义
图是由顶点的有穷非空集合和顶点之间边的集合组成,通常表示为:G(V,E),其中,G表示一个图,V是图G中顶点的集合,E是图G中边的集合。
无向边:若顶点vi到vj 之间的边没有方向,则称这条边为无向边
图结构一定得有顶点
有向边:若顶点vi到vj的边有方向,则称这条边为有向边,也称弧。
无向完全图:
图的存储
图的邻阶矩阵使用两个数组来表述图,一个一维数组存储顶点信息,一个二维数组存储图中边或弧的信息。
图:
顶点数组:
边树组:
[
0
1
1
1
1
0
1
0
1
1
0
1
1
0
1
0
]
\begin{bmatrix} 0 & 1 & 1 & 1 \\ 1 & 0 & 1 & 0 \\ 1 &1 & 0 & 1 \\ 1 & 0 & 1 & 0 \end{bmatrix}
⎣⎢⎢⎡0111101011011010⎦⎥⎥⎤
有向图:
顶点数组:
边树组:
[
0
0
0
1
1
0
1
0
1
1
0
0
0
0
0
0
]
\begin{bmatrix} 0 & 0 & 0& 1 \\ 1 & 0 & 1 & 0 \\ 1 &1 & 0 & 0 \\ 0 & 0 & 0 & 0 \end{bmatrix}
⎣⎢⎢⎡0110001001001000⎦⎥⎥⎤
typedef char VertexType; /*顶点类型由用户定义*/
typedef int EdgeType; /*边上的权值类型由用户定义*/
#define MAXVEX 100 /*最大顶点数,应由用户定义*/
#define INFINITY 65535 /*用65535 来代表∞ */
typedef struct
{
VertexType vexs[MAXVEX];
EdgeType arc[MAXVEX][MAXVEX];
int numVertexes,numEdges;
}MGraph;
/*建立无向图的邻接矩阵表示*/
void CreateMGraph(MGraph *G){
int i,j,k,w;
printf("输入顶点数和边数:\n");
acanf("%d,%d",&G->numVertexes,&G->numEdges);/*输入顶点和边数*/
for(i = 0;i < G->numVertexes;i++)
scanf(&G->vexs[i]);
for (int i = 0; i < G->numVertexes; i++)
{
for (int j = 0; j < i < G->numVertexes; j++)
{
G->arc[i][j] = INFINITY; /*邻接矩阵初始化*/
}
}
for(k = 0;k<G->numEdges;k++){
printf("输入边(vi,vj)上的下标i,下标j和权w:\n");
scanf("%d,%d,%d",&i,&j,&w);
G->arc[i][j] = w;
G->arc[j][i] = G->arc[i][j];/*因为是无向图,矩阵对称*/
}
}
邻接矩阵对于边数相对顶点较少的图,空间浪费严重。
将数组与链表结合存储方法称为邻接表。
顶点:数组存储
边: 每个邻接点使用链表存储
图的遍历
从图的某一顶点出发访遍图中其余顶点,且每个顶点仅被访问一次,这一过程就叫做图的遍历
typedef int Boolean; /* Boolean 是布尔类型,其值是True 或 FALSE*/
Boolean visited[MAX]; /* 访问标志的数组 */
void DFS(MGraph G,int i){
int j;
visited[i] = TRUE;
printf("%c ",G.vexs[i]); /* 打印顶点*/
for(j=0; j < G.numVertexes; j++)
if(G.arc[i][j] == 1 && !visited[j])
DFS(G,j); /* 对为访问的邻接顶点递归调用*/
}
未完待续
未完待续