一、邻接矩阵
1.1 邻接矩阵的定义
邻接矩阵是表示顶点之间相邻关系的矩阵。设G=(V, E)是具有n个顶点的图,顶点序号依次为0,1,... n-1,则G的邻接矩阵是具有如下定义的n阶方阵A:
A[i]l]=1表示顶点i与顶点j邻接,即i与j之间存在边或者弧。
A[i][j]=0表示顶点与顶点j不邻接(0≤i, j≤n-1)。
一般分为4种:有权,无权,有向,无向
这里用电子版天勤中的一张图来表示。自身指向自身一般置为0
1.2 邻接矩阵的创建
邻接矩阵创建的基本思路是:初始化边类,获取一条边的开始节点和结束节点,根据邻接矩阵的类型初始化邻接矩阵的各个点。
本文创建主要是用于测试,边的情况是手写的,可用Scanner类自己写一个输入,解析的方法来进行边的初始化
//邻接矩阵类
@Data
public class MGraph {
/**
* 邻接矩阵定义
*/
int[][] edges;
VertexType[] vex;
int n,e;
public MGraph(EdgeElement[] elements, String[] names, int n, String type) {
this.edges = new int[n][n];
this.vex = new VertexType[n];
//初始化vex数组
for(int j = 0; j < n; j++){
vex[j] = new VertexType(names[j]);
}
//初始化edges矩阵
for (int i = 0; i < elements.length; i++) {
if (elements[i] == null) {
break;
}
int v1, v2;
v1 = elements[i].fromVex;
v2 = elements[i].endVex;
if (v1 < 0 || v1 > n - 1 || v2 < 0 || v2 > n - 1 || v1 == v2) {
System.out.println("边的顶点序号无效,退出运行");
System.exit(0);
}
if (type == GTypeConstant.NoDirectionNoWeight) {
edges[v1][v2] = edges[v2][v1] = 1;
} else if (type == GTypeConstant.NoDirectionWeight) {
edges[v1][v2] = edges[v2][v1] = elements[i].weight;
} else if (type == GTypeConstant.DirectionNoWeight) {
edges[v1][v2] = 1;
} else if (type == GTypeConstant.DirectionNoWeight) {
edges[v1][v2] = elements[i].weight;
} else {
}
}
this.e = elements.length;
this.n = n;
}
/**
* 输出邻接矩阵
*/
public void graphToString(){
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++){
System.out.print(edges[i][j]+" ");
}
System.out.println();
}
}
}
//节点类
public class VertexType {
String no;
String info;
public VertexType(String no) {
this.no = no;
this.info = "";
}
}
//常量类
public class GTypeConstant {
public static final String NoDirectionNoWeight = "0";
public static final String NoDirectionWeight = "1";
public static final String DirectionNoWeight = "2";
public static final String DirectionWeight = "3";
}
//边类
@Data
public class EdgeElement {
int fromVex;
int endVex;
int weight;
public EdgeElement(int fromVex, int endVex, int weight) {
this.endVex = endVex;
this.fromVex = fromVex;
this.weight = weight;
}
public EdgeElement(int fromVex, int endVex) {
this.endVex = endVex;
this.fromVex = fromVex;
this.weight = 1;
}
}
二、邻接表
2.1 邻接表的定义
邻接表是图的-种链式存储结构。所谓邻接表就是对图中的每个顶点i建立-一个单链表,每个单链表的第一个结点存放有关顶点的信息,把这结点看作链表的表头,其余结点存放有关边的信息。因此,邻接表由单链表的表头形成的顶点表和单链表其余结点形成的边表两部分组成。一般顶点表存放顶点信息和指向第一一个边结点指针,边表结点存放与当前顶点相邻接顶点的序号和指向下一个边结点的指针。
2.2 邻接表的创建
邻接表的创建基本思路是:获取边的信息,即开始节点和结束节点。对该节点进行头插法。比如一条边是(1,2),那么在1节点的后面插入2这个节点,在2节点的后面插入1这个节点(无向图)。遍历所有边即可.
边类和常量类在邻接图中已定义,这里不再补充
//邻接表类
public class AGraph {
VertexNode[] adjList;
int verNum;
int edgeNum;
public AGraph(int verNum, int edgeNum, String[] names, EdgeElement[] elements,String type) {
this.verNum = verNum;
this.edgeNum = edgeNum;
//初始化顶点数组
int[] test = new int[5];
adjList = new VertexNode[verNum];
for (int i = 0; i < verNum; i++) {
adjList[i] = new VertexNode(names[i]);
}
if(GTypeConstant.NoDirectionNoWeight.equals(type)){
//初始化边(无权无向)
for (int j = 0; j < edgeNum; j++) {
int v1 = elements[j].fromVex;
int v2 = elements[j].endVex;
ArcNode newNode = new ArcNode();
//新节点下标为v1
newNode.adjvex = v1;
//头插
newNode.nextArc = adjList[v2].firstArc;
adjList[v2].firstArc = newNode;
ArcNode newNode2 = new ArcNode();
newNode2.adjvex = v2;
newNode2.nextArc = adjList[v1].firstArc;
adjList[v1].firstArc = newNode2;
}
}
}
public void graphToString() {
System.out.println("输出邻接表存储情况:");
ArcNode en;
for (int i = 0; i < verNum; i++) {
System.out.print(adjList[i].name);
en = adjList[i].firstArc;
while (en != null) {
System.out.print("->" + adjList[en.adjvex].name);
en = en.nextArc;
}
System.out.println();
}
}
}
//顶点信息类
public class VertexNode {
public String name;
public ArcNode firstArc;
public VertexNode(String name){
this.name = name;
this.firstArc = null;
}
}
//边节点类
public class ArcNode {
int adjvex;
int value;
ArcNode nextArc;
}
三、测试代码
public static void main(String[] args) {
//初始化邻接矩阵,6个节点
int n = 6;
EdgeElement[] elements = new EdgeElement[6];
elements[0] = new EdgeElement(0, 1);
elements[1] = new EdgeElement(0, 2);
elements[2] = new EdgeElement(0, 3);
elements[3] = new EdgeElement(1, 2);
elements[4] = new EdgeElement(1, 4);
elements[5] = new EdgeElement(4, 5);
String[] names = {"0", "1", "2", "3", "4", "5"};
//邻接矩阵
MGraph mGraph = new MGraph(elements, names, n, GTypeConstant.NoDirectionNoWeight);
mGraph.graphToString();
//邻接表形式
AGraph aGraph = new AGraph(6, 6, names, elements, GTypeConstant.NoDirectionNoWeight);
aGraph.graphToString();
输出结果:
0 1 1 1 0 0
1 0 1 0 1 0
1 1 0 0 0 0
1 0 0 0 0 0
0 1 0 0 0 1
0 0 0 0 1 0
输出邻接表存储情况:
0->3->2->1
1->4->2->0
2->1->0
3->0
4->5->1
5->4