一、图(Graph)
图(Graph)结构也是一种非线性数据结构,图结构在实际生活中具有丰富的例子。例如,通信网络、交通网络、人际关系网络等都可以归结为图结构。图结构的组织形式要比树结构更为复杂,因此,图结构对存储和遍历等操作具有更高的要求。
图是一种善于处理关系型数据的数据结构,使用它可以很轻松地表示数据之间是如何关联的。
1、图结构
一个典型的图结构包括如下内容。
・顶点(Vertex):图中的数据元素。
・边(Edge):图中连接这些顶点的线。
所有的顶点构成一个顶点集合,所有的边构成边集合,一个完整的图结构由顶点集合和边集合组成。
2、图的基本概念
1)无向图
如果一个图结构中,所有的边都没有方向性,那么这种图便称为无向图。
2)有向图
如果一个图结构中,边有方向性,那么这种图便称为有向图。
3)顶点的度(Degree)
连接顶点的边的数量称为该顶点的度。顶点的度在有向图和无向图中具有不同的表示。对于无向图,一个顶点V的度比较简单,其是连接该顶点的边的数量,记为D(V)。
对于有向图要稍复杂些,根据连接顶点V的边的方向性,一个顶点的度有入度和出度之分。
4)邻接顶点
邻接顶点是指图结构中一条边的两个顶点。邻接顶点在有向图和无向图中具有不同的表示。
对于有向图要稍复杂些,根据连接顶点V的边的方向性,两个顶点分别称为起始顶点(起点或始点)和结束顶点(终点)。
5)无向完全图
如果在一个无向图中,每两个顶点之间都存在一条边,那么这种图结构称为无向完全图。
6)有向完全图
如果在一个有向图中,每两个顶点之间都存在方向相反的两条边,那么这种图结构称为有向完全图。
7)子图
子图的概念类似子集合,由于一个完整的图结构包括顶点和边,因此,一个子图的顶点和边都应该是另一个图结构的子集合。
8)路径
路径即图结构中两个顶点之间的连线,路径上边的数量称为路径长度。
9)连通、连通图和连通分量
・如果无向图中任意两个顶点都是连通的,那么这个图便称为连通图。如果无向图中包含两个顶点是不连通的,那么这个图便称为非连通图。
・无向图的极大连通子图称为该图的连通分量。
10)强连通图和强连通分量
・如果有向图中任意两个顶点都是连通的,则称该图为强连通图。如果有向图中包含两个顶点不是连通的,则称该图为非强连通图。
・有向图的极大强连通子图称为该图的强连通分量。
11)权
图的各个边并没有赋予任何含义。在实际的应用中往往需要将边表示成某种数值,这个数值便是该边的权(Weight)。无向图中加入权值,则称为无向带权图。有向图中加入权值,则称为有向带权图。
12)网(Network)
网即边上带有权值的图的另一名称。
二、图的实现
使用Java的ArrayList实现。
// Java code to demonstrate Graph representation
// using ArrayList in Java
import java.util.*;
class Graph {
// A utility function to add an edge in an
// undirected graph
static void addEdge(ArrayList<ArrayList<Integer> > adj,
int u, int v)
{
adj.get(u).add(v);
adj.get(v).add(u);
}
// A utility function to print the adjacency list
// representation of graph
static void
printGraph(ArrayList<ArrayList<Integer> > adj)
{
for (int i = 0; i < adj.size(); i++) {
System.out.println("\nAdjacency list of vertex"
+ i);
System.out.print("head");
for (int j = 0; j < adj.get(i).size(); j++) {
System.out.print(" -> "
+ adj.get(i).get(j));
}
System.out.println();
}
}
// Driver Code
public static void main(String[] args)
{
// Creating a graph with 5 vertices
int V = 5;
ArrayList<ArrayList<Integer> > adj
= new ArrayList<ArrayList<Integer> >(V);
for (int i = 0; i < V; i++)
adj.add(new ArrayList<Integer>());
// Adding edges one by one
addEdge(adj, 0, 1);
addEdge(adj, 0, 4);
addEdge(adj, 1, 2);
addEdge(adj, 1, 3);
addEdge(adj, 1, 4);
addEdge(adj, 2, 3);
addEdge(adj, 3, 4);
printGraph(adj);
}
}