邻接表是数组与链表相结合的存储方法,相比于顺序存储结构(邻接矩阵),节省空间。
来个小例子(无向图):
图1
图1邻接表的结构:
邻接表用链表来存储邻接点(分两个域,一个存顶点下标,一个存下一个邻接点的引用),通过一个类(我用了内部类,所以是private)定义邻接点:
private class AdgvexType {
int verNum = -1;//存储顶点数组下标,默认零
AdgvexType adg = null;//存储下一个邻接点的引用
public int getVerNum() {
return verNum;
}
public void setVerNum(int verNum) {
this.verNum = verNum;
}
public int getWeightNum() {
return weightNum;
}
public void setWeightNum(int weightNum) {
this.weightNum = weightNum;
}
public AdgvexType getAdg() {
return adg;
}
public void setAdg(AdgvexType adg) {
this.adg = adg;
}
@Override
public String toString() {
return "AdgvexType [verNum=" + verNum + ", weightNum=" + weightNum
+ "]";
}
}
邻接表用数组存储图的顶点,数组中每个元素包含两个域(一个存顶点,一个存它第一个临界点的引用),定义顶点数组:
private VertexeType[] verArr;// 顶点数组
// 顶点数据
private class VertexeType {
String vertexe = null;//存储顶点
AdgvexType adg = null;//存储第一个邻接点的引用
public VertexeType() {
}
public VertexeType(String vertexe) {
this.vertexe = vertexe;
}
public String getVertexe() {
return vertexe;
}
public void setVertexe(String vertexe) {
this.vertexe = vertexe;
}
public AdgvexType getAdg() {
return adg;
}
public void setAdg(AdgvexType adg) {
this.adg = adg;
}
@Override
public String toString() {
return "VertexeType [vertexe=" + vertexe + ", adg=" + adg + "]";
}
}
再说说带权值的有向图(在原来的基础上):
图2
需要多记录一项属性(权值),对邻接点类型加一个域,来存储权值,结构如下:
对class AdgvexType类加一条属性(成员变量)即可:
int weightNum = 0;
通过构造方法为顶点数组赋值:
public AdjacencyList(String[] arr) {
this.MAXVEX = arr.length;
this.verArr = new VertexeType[this.MAXVEX];
for (int i = 0; i < arr.length; i++) {
this.verArr[i] = new VertexeType(arr[i]);
}
}
通过二维数组添加所有邻接点:
public void addAdg(String[][] arr) {
for (int i = 0; i < arr.length; i++) {
AdgvexType temp = null;
int[] pos = this.getPosition(arr[i]);
AdgvexType adg = new AdgvexType();
adg.setWeightNum(Integer.valueOf( arr[i][2]));//设置权值
adg.setVerNum(pos[1]);
temp = this.verArr[pos[0]].getAdg();
if (temp == null) {
this.verArr[pos[0]].setAdg(adg);
continue;
}
while (true) {
if (temp.getAdg() != null) {
temp = temp.getAdg();
} else {
temp.setAdg(adg);
break;
}
}
}
}
//查找顶点位置
private int[] getPosition(String[] arr) {
int[] arrInt = new int[2];
for (int i = 0; i < this.MAXVEX; i++) {
if (this.verArr[i].getVertexe().equals(arr[0])) {
arrInt[0] = i;
break;
}
}
for (int i = 0; i < this.MAXVEX; i++) {
if (this.verArr[i].getVertexe().equals(arr[1])) {
arrInt[1] = i;
break;
}
}
return arrInt;
}
测试代码:
package com.nuc.Graph;
public class TestAdg {
public static void main(String[] args) {
// TODO Auto-generated method stub
// TODO Auto-generated method stub
String[] str={"v0","v1","v2","v3"};
AdjacencyList adj=new AdjacencyList(str);
String[][] edges=new String[][]{
{"v0","v3","5"},//顶点,顶点,权值
{"v1","v0","1"},
{"v1","v2","3"},
{"v2","v0","7"},
{"v2","v1","4"}
};
adj.addAdg(edges);
adj.show();
}
}
下边是完整代码:
import java.util.Arrays;
public class AdjacencyList {
private int MAXVEX;// 顶点数组长度
private VertexeType[] verArr;// 顶点数组
// 顶点数据
private class VertexeType {
String vertexe = null;
AdgvexType adg = null;
public VertexeType() {
}
public VertexeType(String vertexe) {
this.vertexe = vertexe;
}
public String getVertexe() {
return vertexe;
}
public void setVertexe(String vertexe) {
this.vertexe = vertexe;
}
public AdgvexType getAdg() {
return adg;
}
public void setAdg(AdgvexType adg) {
this.adg = adg;
}
@Override
public String toString() {
return "VertexeType [vertexe=" + vertexe + ", adg=" + adg + "]";
}
}
// 边表节点
private class AdgvexType {
int verNum = -1;
int weightNum = 0;
AdgvexType adg = null;
public int getVerNum() {
return verNum;
}
public void setVerNum(int verNum) {
this.verNum = verNum;
}
public int getWeightNum() {
return weightNum;
}
public void setWeightNum(int weightNum) {
this.weightNum = weightNum;
}
public AdgvexType getAdg() {
return adg;
}
public void setAdg(AdgvexType adg) {
this.adg = adg;
}
@Override
public String toString() {
return "AdgvexType [verNum=" + verNum + ", weightNum=" + weightNum
+ "]";
}
}
// 初始化,为顶点数组赋值
public AdjacencyList(String[] arr) {
this.MAXVEX = arr.length;
this.verArr = new VertexeType[this.MAXVEX];
for (int i = 0; i < arr.length; i++) {
this.verArr[i] = new VertexeType(arr[i]);
}
}
public void addAdg(String[][] arr) {
for (int i = 0; i < arr.length; i++) {
AdgvexType temp = null;
int[] pos = this.getPosition(arr[i]);
AdgvexType adg = new AdgvexType();
adg.setVerNum(pos[1]);
temp = this.verArr[pos[0]].getAdg();
if (temp == null) {
this.verArr[pos[0]].setAdg(adg);
continue;
}
while (true) {
if (temp.getAdg() != null) {
temp = temp.getAdg();
} else {
temp.setAdg(adg);
break;
}
}
}
}
private int[] getPosition(String[] arr) {
int[] arrInt = new int[2];
for (int i = 0; i < this.MAXVEX; i++) {
if (this.verArr[i].getVertexe().equals(arr[0])) {
arrInt[0] = i;
break;
}
}
for (int i = 0; i < this.MAXVEX; i++) {
if (this.verArr[i].getVertexe().equals(arr[1])) {
arrInt[1] = i;
break;
}
}
return arrInt;
}
public void show() {
for (VertexeType v : verArr) {
if (v.getAdg() == null) {
System.out.println(v);
continue;
}
AdgvexType temp = v.getAdg();
String s = v + "-->" + temp;
while (true) {
if (temp.getAdg() != null) {
temp = temp.getAdg();
s +="-->"+ temp;
} else {
System.out.println(s);
break;
}
}
}
}
}