图
图是一种各个数据对象间存在多对多关系的数据结构
图的接口Interface
public interface IGraph {
void createGraph();//创建图
int getVexNum();//统计顶点数
int getArcNum();//统计边数
Object getVex(int v) throws Exception;//返回v位置对应的顶点
int locateVex(Object vex);//查找vex在图中的位置
int firstAdjVex(int v) throws Exception;//返回顶点v的第一个邻接点
int nextAdjVex(int v,int w) throws Exception;//返回顶点v相对于邻接顶点w的下一个邻接顶点,若w为v的最后一个邻接顶点,返回-1
}
图的类型
图分为无向图,有向图,无向网,有向网四种,其中无向网,有向网在无向图,有向图的基础上,在各边上加上了权值,我们可以使用枚举类型enum定义图的类型
public enum GraphKind {
UDG,//undirected graph 无向图
DG,//directed graph 有向图
UDN,//undirected network 无向网
DN//directed network 有向网
}
图的表示
图的表示方法有邻接矩阵,邻接表,十字链表,邻接多重表等等,这里我们只介绍邻接矩阵和邻接表,因为这两种方法比较常见,而且代码实现起来也相对简单一些。
邻接矩阵
邻接矩阵的大小为N*N,N为图中顶点的个数,第i行第j列表示顶点Vi和Vj的边,若为0,则表示顶点Vi和Vj没有边相连,若为1则表示有边相连,若是不为1的其他数则表示顶点Vi和Vj相连边的权值
邻接矩阵的实现:
import java.util.*;
public class MGraph implements IGraph{
public final static int INFINITY=Integer.MAX_VALUE;
private GraphKind kind;
private int vexNum,arcNum;
private Object[] vexs;
private int[][] arcs;
public MGraph() {
this(null,0,0,null,null);
}
public MGraph(GraphKind kind,int vexNum,int arcNum,Object[] vexs,int[][] arcs) {
this.kind=kind;
this.vexNum=vexNum;
this.arcNum=arcNum;
this.vexs=vexs;
this.arcs=arcs;
}
@Override
public void createGraph() {
Scanner sc=new Scanner(System.in);
System.out.println("请输入图的类型");
GraphKind kind=GraphKind.valueOf(sc.next());
switch(kind) {
case UDG:
createUDG();
return ;
case DG:
createDG();
return;
case UDN:
createUDN();
return ;
case DN:
createDN();
return ;
}
}
public void createUDG() {
Scanner sc =new Scanner(System.in);
System.out.println("请输入图的顶点数和边数");
vexNum=sc.nextInt();
arcNum=sc.nextInt();
vexs=new Object[vexNum];
for(int i=0;i<vexNum;i++) {
vexs[i]=sc.next();
}
arcs=new int[vexNum][vexNum];
for(int i=0;i<vexNum;i++) {
for(int j=0;j<vexNum;j++)
arcs[i][j]=INFINITY;
}
System.out.println("请输入边的两个顶点");
for(int i=0;i<arcNum;i++) {
int u=locateVex(sc.next());
int v=locateVex(sc.next());
arcs[u][v]=arcs[v][u]=1;
}
}
public void createDG() {
Scanner sc =new Scanner(System.in);
System.out.println("请输入图的顶点数和边数");
vexNum=sc.nextInt();
arcNum=sc.nextInt();
vexs=new Object[vexNum];
for(int i=0;i<vexNum;i++) {
vexs[i]=sc.next();
}
arcs=new int[vexNum][vexNum];
for(int i=0;i<vexNum;i++) {
for(int j=0;j<vexNum;j++)
arcs[i][j]=INFINITY;
}
System.out.println("请输入边的两个顶点及权值");
for(int i=0;i<arcNum;i++) {
int u=locateVex(sc.next());
int v=locateVex(sc.next());
arcs[u][v]=1;
}
}
public void createUDN(){
Scanner sc =new Scanner(System.in);
System.out.println("请输入图的顶点数和边数");
vexNum=sc.nextInt();