图的基本介绍:
为什么要有图:
- 前面我们学了线性表和树
- 线性表局限于一个直接前驱和一个直接后继的关系
- 树也只能有一个直接前驱也就是父节点
- 当我们需要表示多对多的关系时, 这里我们就用到了图
图的举例说明:
图(Graph)是由顶点的有穷非空集合和顶点之间边的集合组成,通常表示为:G(V,E),其中,G表示一个图,V(vertex)是图G中顶点的集合,E(edge)是图G中边的集合。
图的常用概念:
- 顶点(vertex)
- 边(edge)
- 路径 :顶点v到顶点w之间的一条路径是指顶点序列v, a, b, c, d ···, w。
- 路径长度:路径上边的数目称为路径长度
- 无向图(右图)
- 有向图
- 顶点的度(degree): 就是顶点关联边的数目。在有向图中,分为出度:方向背向顶点的边;入度:方向指向顶点的边。有向图的度为入度和出度的和。
- 联通性:在无向图中,从一个顶点出发,有到达其他任意顶点的路径,则称这个图是联通的。具有这种性质的有向图叫做强连通图。
- 如果把一个有向图的所有有向边去掉方向形成的无向图被称为这个有向图的基础图,也叫基图。
- 有向图不是强连通,但是他的基图是连通的,则被称为弱连通。
图的表示方式
图的表示方式有两种:二维数组表示(邻接矩阵);链表表示(邻接表)。
- 邻接矩阵
邻接矩阵是表示图形中顶点之间相邻关系的矩阵,对于n个顶点的图而言,矩阵是的row和col表示的是1…n个点。
- 邻接表
1)、邻接矩阵需要为每个顶点都分配n个边的空间,其实有很多边都是不存在,会造成空间的一定损失.
2)、邻接表的实现只关心存在的边,不关心不存在的边。因此没有空间浪费,邻接表由数组+链表组成
说明:
1、标号为0的结点的相关联的结点为 1 2 3 4
2、标号为1的结点的相关联结点为0 4,
3、标号为2的结点相关联的结点为 0 4 5
…
图的创建案例分析:
要求: 代码实现如下图结构.
思路分析
(1) 存储顶点String信息,使用 ArrayList<String>
(2) 保存矩阵 int[][] edges ==>用来表示个顶点之间是否相连
详细代码:
package graph;
import java.util.ArrayList;
import java.util.Arrays;
public class Graph {
// 存放每个结点内的数据
private ArrayList<String> vertexList;
// 存放图对应的邻接矩阵
private int[][] edges;
// 存放边的数目
private int numOfEdges;
public static void main(String[] args) {
int n = 5;
Graph graph = new Graph(5);
String[] vertexValue = {
"A", "B", "C", "D", "E" };
// 建立各顶点所对应的值
for (String vertex : vertexValue) {
graph.insertVertex(vertex);
}
// 构造边的关系
graph.insertEdges(0, 0, 1);
graph.insertEdges(0, 2, 1);
graph.insertEdges(1, 2, 1);
graph.insertEdges(1, 3, 1);
graph.insertEdges(1, 4, 1);
graph.showGraph();
}
/**
*
* @param 顶点个数
*/
public Graph(int n) {
edges = new int[n][n];
vertexList = new ArrayList<String>(n);
}
/**
*
* @Title: insertVertex
* @Description: 向顶点中加入该顶点的数据
* @param @param vertex 要插入的数据
* @return void 返回类型
*/
public void insertVertex(String vertex) {
vertexList.add(vertex);
}
/**
*
* @Title: insertEdges
* @Description: 将邻接矩阵各个结点之间的关系建立起来,1代表相连,0代表不相连
* @param @param v1 代表下标为v1的顶点
* @param @param v2 代表下标为v2的顶点
* @param @param weight 权值,不是0就是1
* @return void 返回类型
*/
public void insertEdges(int v1, int v2, int weight) {
edges[v1][v2] = weight;
edges[v2][v1] = weight;
numOfEdges++;
}
// 返回结点数
public int getNumOfVertex() {
return vertexList.size();
}
// 返回边数
public int getNumOfEdges() {
return numOfEdges;
}
// 返回i对应的数据
public String getValueByyIndex(int i) {
return vertexList.get(i);
}
// 返回v1和v2的权值
public int getWeight(int v1, int v2) {
return edges[v1][v2];
}
// 显示图对应的矩阵
public void showGraph() {
for (int[] link : edges) {
System.out.println(Arrays.toString(link));
}
}
}