图的基本概念和术语
定义和基本术语
- ➢图( graph)是种网状数据结构 ,图是由非空的顶点集合和一个描述顶点之间关系的集合组成。
- ➢图由顶点和边组成,顶点表示对象,边表示两个对象间的连接关系。
- ➢图大体分两种,边没有指向性的叫无向图,边具有指向性的叫有向图。
- ➢边可以带权值,称为带权图。
无向图术语
- ➢两个顶点之间如果有边连接,视为两个顶点相邻
- ➢相邻顶点的序列称为路径
- ➢起点和终点重合的路径称为圈
- ➢任意两点之间都存在路径连接的图称为连通图
- ➢顶点连接的边数叫做这个顶点的度
树和图的关系
- ➢没有圈的连通图,就是树
- ➢没有圈的非连通图,就是森林
- ➢一棵树的边数等于顶点数-1
- ➢边数等于顶点数-1的连通图,就是树
有向图的术语
- ➢没有圈的有向图,叫做DAG ( Directed Acyclic Graph ,有向无环图)
- ➢拓扑排序定义:将DAG中的顶点以线性方式进行排序。即对于任何自顶点u到顶点v的有向边u->V ,在最后的排序结果中, 顶点u总是在顶点v的前面。这样的排序结果,称为拓扑序。
图的表示
邻接矩阵
- ➢无向图的邻接矩阵是对称矩阵,有向时不一定;
- ➢不带权时用1/0表示是否有边;带权时,数值就是权值
邻接表
- ➢邻接表更加节约空间
- ➢但是,查询两点是否有边需遍历链表
- ➢而且,保存权值需要另外存:储一个边集
下面用代码表示:
邻接表的头结点类:
package 图的表示;
import java.util.ArrayList;
import java.util.List;
/*
* 邻接表的头结点
*/
public class GraphNodeAl {
public int val; //表示节点的位置
private List<GraphNodeAl> neighbors; //节点所在的链表,存储所有与该节点相邻的节点
public GraphNodeAl(int val){
this.val = val;
}
//获取与节点相邻的节点i
public GraphNodeAl getNeighbor(int i){
return neighbors.get(i);
}
//添加与节点相邻的节点
public void add(GraphNodeAl node){
if(this.neighbors == null){
this.neighbors = new ArrayList<GraphNodeAl>();
}
neighbors.add(node);
}
//返回与该节点相邻的节点个数
public int size(){
return this.neighbors.size();
}
}
图的实现代码:
package 图的表示;
/*
* 用邻接表来表示图
*/
public class Graph {
public static void main(String[] args) {
//创建图中的九个顶点
GraphNodeAl n1 = new GraphNodeAl(1);
GraphNodeAl n2 = new GraphNodeAl(2);
GraphNodeAl n3 = new GraphNodeAl(3);
GraphNodeAl n4 = new GraphNodeAl(4);
GraphNodeAl n5 = new GraphNodeAl(5);
GraphNodeAl n6 = new GraphNodeAl(6);
GraphNodeAl n7 = new GraphNodeAl(7);
GraphNodeAl n8 = new GraphNodeAl(8);
GraphNodeAl n9 = new GraphNodeAl(9);
//为n1节点添加所有与n1相连的节点
n1.add(n2);
//为n2添加所有与n2相邻的节点
n2.add(n1);
n2.add(n4);
n2.add(n5);
n2.add(n8);
n3.add(n4);
n4.add(n2);
n4.add(n3);
n5.add(n2);
n5.add(n6);
n5.add(n7);
n5.add(n9);
n6.add(n5);
n7.add(n5);
n8.add(n2);
n9.add(n5);
}
}