图:
由顶点和顶点之间的边的集合组成,记为:G(V,E)。
顶点之间的边没有方向,为无向边(A,B),该图为无向图。如果任意两顶点之间都存在边,则为无向完全图,n顶点有n*(n-1)/2条边。
顶点之间的边有方向,为有向边或弧<A,B>,该图为有向图。如任意两顶点之间都存在方向互反两条弧,则为完全有向图,n顶点有n*(n-1)条边。
带权图:通常称为网。即边上有自己的权值。
度:与该顶点相关联的边的数目TD(V)。 有向图中入度:指向该顶点的边的数目ID(V) 有向图中出度:该点指出的边的数目OD(V) TD(V)=ID(V)+OD(V)
路经长度:路径上的边的数目。回路:环,第一个顶点到最后一个顶点相同的路经。 简单回路:第一个顶点和最后一个顶点外,其余顶点不重复出现的回路。
连通:无向图中,从顶点A到顶点B有路经,则称为A和B是连通的。 连通图:图中任意两个顶点都是连通的。
强连通图:有向图中,每一对顶点之间都存在路经。
图的存储:
1、邻接矩阵:用两个数组来表示图。一个一维数组表示图的顶点信息,一个二维数组表示图的边或弧的信息。
typedef char VertexType; typedef int EdgeType; const int MAXVEX = 100; struct MGraph { VertexType vexs[MAXVEX];//存储顶点 EdgeType arc[MAXVEX][MAXVEX];//存储边的信息 int numVertexes; int numEdges; };
2、邻接表:图中顶点用一维数组存储,且每个数据单元还存储一个指向第一个邻接点的指针。每个顶点的所有邻接点构成一个线性表,用单链表存储。无向图中,该单链表为该顶点的边表;有向图它则为该顶点作为起点的出边表。
typedef char VertexType; typedef int EdgeType; const int MAXVEX = 100; struct EdgeNode//边表结构 { int adjvex; EdgeType weight; EdgeNode *next; }; struct VertexNode//顶点结构 { VertexType data; EdgeNode *firstedge; }; struct GraphAdjList//图结构 包含顶点结构的数组和顶点数目边的数目 { VertexNode adjList[MAXVEX]; int numVertexes; int numEdges; };
3、边集数组:两个一维数组构成。一个存储顶点信息;另一个存储边的信息:每个边数组元素包括一条边的起点下标、终点下标和权值。
typedef char VertexType; typedef int EdgeType; const int MAXVEX = 100; const int MAXEDGE = 1000; struct EdgeNode// 边节点数据结构 { int begin; int end; int weight; }; struct MGraph//图的结构 { VertexType vexs[MAXVEX]; //顶点数组 EdgeNode edges[MAXEDGE]; //边数组 int numVertexes; int numEdges; };
还有其他的十字链表,邻接多重表等,其实就是在前两种结构的基础上的增加改进,用的不多,看多了也记不住,还是就记住上面两种吧,也最常用。