图结构
图(Graph)结构也是一种非线性结构,图结构在实际生活中具有丰富的例子。例如:通信网络、人际关系网络等。
什么是图结构:
之前说的树结构基本特点是数据之间具有层次关系,每一层的元素可以和多个下层元素关联,但是只能和一个上层元素关联。如果将此规则进一步扩展,也就是每个元素数据之间可以任意关联,这就构成了一个图结构。正是这种任意关联性导致了图结构中数据关系的复杂性。
一个典型的图结构包括以下内容:
- 定点(Vertex):图中的数据元素。
- 边(Edge):图中连接这些顶点的线。
所有的顶点构成一个顶点集合,所有的边构成边集合,一个完整的图结构由顶点集合和边集合组成。一般标记为:
- G=(V,E)
- G=(V(G),E(G))
其中,V(G)表示图结构中所有顶点的集合,顶点可以用不同的数字或者字母表示。E(G)是图中边的集合,每条边由所连接的两个顶点表示。
上图就可以表示为:
V(G)={V1,V2,V3,V4,V5,V6}
E(G)={(V1,V2),(V1,V3),(V1,V5),(V2,V4),(V3,V5),(V4,V5),(V4,V6),(V5,V6)}
基本概念
无向图
如果一个图结构中,所有的边都没有方向性,那么这种图便称为无向图。
有向图
如果一个图结构中,边有方向性,那么这种图便称为有向图。
顶点的度
连接顶点的边的数量称为顶点的度。
对于有向图连接顶点的v是有方向的,度就有入度和出度之分。
- 入度是已该顶点为端点的入边数量,记为ID(V)。
- 出度是以该顶点为端点的出边数量,记为OD(V)。
邻接顶点
邻接顶点是指图结构中一条边的两个顶点。
无向完全图
如果在一个无向图中,每两个顶点之间都有一条边,那么这种图结构称为无向完全图。
有向完全图
如果在一个有向图中,每两个顶点之间都存在方向相反的两条边,那么这种图结构称为有向完全图。
路径
路径即图结构中两个顶点之间的连线,路径上边的数量称为路径长度。两个顶点之间的路径可能途径多个其他顶点,两个顶点之间的路径也可能不止一条,相应的路径长度可能不一样。
强连通图和强连通分量
与无向图类似,在有向图中也有连通的概念。
- 如果两个顶点之间有路径,也称这两个顶点是连通的。需要注意的是,有向图中边是有方向的。因此。1到2是连通的,但是从2到1不一定连通。
- 如果有向图中任意两个顶点都是连通的,则称该图为强连通图。
- 有向图的极大强连通子图称为该图的强连通分量。
权
实际的应用中往往需要将边长表示成某种数值,这个数值便是该边的权。
public class GraphMatrix {
static final int MaxNum = 20;
static final int MaxCalue = 65535;
char[] Vertex = new char[MaxNum]; // 保存顶点信息 序号或字母
int GType; //图的类型 0 无向图 1 有向图
int VertexNum; // 顶点数量
int EdgeNum; // 边的数量
int[][] EdgeWeight=new int[MaxNum][MaxNum]; // 保存边的权
int[] isTrav = new int[MaxNum]; // 遍历标志
}
图操作
public class P2_6 {
static Scanner input = new Scanner(System.in);
// 创建邻接矩阵
static void CreateGraph(GraphMatrix GM){
int i,j,k; //
int weight; //权
char EstartV,EendV; //边的起始顶点
System.out.printf("输入图中各顶点信息");
for (i=0;i<GM.VertexNum;i++){ // 输入顶点
System.out.printf("第几个顶点"+(i+1));
GM.Vertex[i]=(input.next().toCharArray())[0]; // 保存到各顶点的数据元素中
}
System.out.printf("输入构成各边的顶点及权值");
for (k=0;k<GM.EdgeNum;k++){
System.out.printf("第"+(k+1)+"条边");
EstartV = input.next().charAt(0);
EendV = input.next().charAt(0);
weight = input.nextInt();
for(i=0;EstartV!=GM.Vertex[i];i++); // 在已有顶点中查找开始结点
for(j=0;EendV!=GM.Vertex[j];j++); // 在已有顶点中查找终结点
GM.EdgeWeight[i][j]=weight; // 对应位置保存权值,表示有一条边
if(GM.GType == 0){
GM.EdgeWeight[j][i] = weight; // 在对角位置保存权值
}
}
}
// 清空矩阵
static void ClearGraph(GraphMatrix GM){
int i,j;
for (i = 0; i <GM.VertexNum ; i++) {
for (j = 0; j <GM.VertexNum ; j++) {
GM.EdgeWeight[i][j] = GraphMatrix.MaxCalue;
}
}
}
// 输出邻接矩阵
static void OutGraph(GraphMatrix GM){
int i,j;
for(j=0;j<GM.VertexNum;j++){
System.out.printf(GM.Vertex[j]+"");
}
System.out.println("");
for(i=0;i<GM.VertexNum;i++){
System.out.printf(GM.Vertex[i]+"");
for(j=0;j<GM.VertexNum;j++){
if(GM.EdgeWeight[i][j]==GraphMatrix.MaxCalue){
System.out.printf("Z");
}else {
System.out.printf(GM.EdgeWeight[i][j]+"");
}
}
System.out.println();
}
}
}