图(Graph)G由两个集合V和E组成,记为G=(V,E),其中V是顶点的有穷非空集合,E是V中顶点偶对的有穷集合(即就是边集)。(图中的边集允许为空)
有向图:顶点对<x,y>是有序的,他表示从顶点x到顶点y的一条有向边,<x,y>与<y,x>表示两条不同的有向边。
无向图:顶点对(x,y)是无序的,它表示与顶点x和顶点y相关联的一条边,(x,y)和(y,x)是同一条边。
子图:假设有两个图G=(V,E)和G1=(V1,E1),如果V1⊆V且E1⊆E,称G1是G的子图。
有向完全图:对于有向图,任意两个顶点之间都存在方向相反的两条边,即具有n(n-1)条边。
对于无向图:任意两个顶点之间都存在边,即具有n(n-1)/2条边。
简单图:不存在自环(顶点到其自身的边)和重边(完全相同的边)的图。
稀疏图:有很少条边或弧的图称为稀疏图,反之称为稠密图。
权:从图中一个顶点到另一个顶点的距离或耗费。
网:带有权重的图。
邻接点:无向图G,相邻的两个顶点
度:与顶点相关联的边的数目。
出度:出度表示顶点为起点的边的数目。
入度:入度表示顶点为终点的边的数目。
路径:顶点V顶点V1的路劲是一个顶点序列。
路径长度:是一条路径上经过的边和弧的数目。
回路或环:第一个顶点和最后一个顶点相同的路径称为回路或环。
简单路径:顶点中不重复出现的路径。
简单回路:除了第一个顶点和最后一个顶点之外,其余顶点不重复出现的回路。
连通图:图中任意两个顶点都是连通的。
极大连通子图:包含尽可能多的顶点,即找不到另外一个顶点,使得此顶点能够连接到此极大连通子图中的任意一个顶点。
连通分量:极大连通子图的数量。
强连通图:在有向图中,对于它任意两个顶点,从V1到V2和从V2到V1都存在路径。
强连通分量:有向图中的极大连通子图。
连通图的生成树:包含图中的全部顶点你,但只有足以构成一棵树的n-1条边。
最小生成树:生成树的边的权重之和是最小的树。
邻接矩阵:
邻接表:
图的Java实现:
(1)边的构建
public class Edge {
//权重
public int weight;
//从哪个节点出发
public Node from;
//到那个节点
public Node to;
//构造方法
public Edge(int weight, Node from, Node to) {
this.weight = weight;
this.from = from;
this.to = to;
}
}
(2)节点的构建
import java.util.ArrayList;
public class Node {
//标记定点,也可以是string类型
public int value;
//入度
public int in;
//出度
public int out;
//从本身出发,能够到达的下一个节点
public ArrayList<Node> nexts;
//从本身出发,发散出边的集合
public ArrayList<Edge> edges;
public Node(int value) {
super();
this.value = value;
this.in = 0;
this.out = 0;
this.nexts = new ArrayList<>();
this.edges = new ArrayList<>();
}
}
(3)图的构建
import java.util.HashMap;
import java.util.HashSet;
public class Graph {
//点的集合
public HashMap<Integer, Node> nodes;
//边的集合
public HashSet<Edge> edges;
public Graph() {
nodes = new HashMap<>();
edges = new HashSet<>();
}
}
(4)生成图
//生成图
public class GraphGenerator {
public static Graph createGraph(Integer[][] matrix){
//创建一个图
Graph graph=new Graph();
for (int i = 0; i < matrix.length; i++) {
//首先获取边的起点、终点和权值
Integer from = matrix[i][0];
Integer to = matrix[i][0];
Integer weight = matrix[i][0];
//如果起点不在图的顶点集中,就创建起点节点
if (!graph.nodes.containsKey(from)) {
graph.nodes.put(from, new Node(from));
}
//如果终点不在图的顶点集中,就创建终点节点
if (!graph.nodes.containsKey(to)) {
graph.nodes.put(to, new Node(to));
}
//从节点集中获取起点节点和终点节点
Node fromNode=graph.nodes.get(from);
Node toNode = graph.nodes.get(to);
//利用权值、起点节点和终点节点构建有向边
Edge newedge = new Edge(weight, fromNode, toNode);
//nexts是从本身出发,能够到达的下一个节点的集合,所以把终点加入
fromNode.nexts.add(toNode);
fromNode.out++;
toNode.in++;
//edges是从本身出发,发散出边的集合,把边加入起点节点
fromNode.edges.add(newedge);
//把边加入图的边集
graph.edges.add(newedge);
}
return graph;
}
}
matrix传入的是一个二维数组:包括起点、终点和权值