邻接矩阵是一种表示图的数据结构,通过二维数组来表示图中的顶点和边的关系。在邻接矩阵中,行和列分别代表图中的顶点,而矩阵中的元素表示顶点之间是否有边,以及边的权重(在带权图中)。以下是邻接矩阵的基本概念和使用方法:
1. 基本概念:
- 顶点(Vertex): 图中的节点。
- 边(Edge): 顶点之间的连接线。
- 有向图(Directed Graph): 边有方向的图。
- 无向图(Undirected Graph): 边没有方向的图。
- 邻接矩阵(Adjacency Matrix): 一个二维数组,用于表示图的结构。
2. 邻接矩阵的表示方法:
- 图的大小: 如果图有
n
个顶点,那么邻接矩阵是一个n x n
的二维数组。 - 矩阵元素: 矩阵中的元素
matrix[i][j]
表示顶点i
到顶点j
是否有边。对于无权图,通常用 0 或 1 表示是否相邻;对于带权图,可以使用权重值表示。
3. 邻接矩阵的优点和缺点:
-
优点:
- 直观:易于理解和实现。
- 查询两个顶点之间是否有边的操作很快速,只需查看数组中的一个元素。
-
缺点:
- 浪费空间:对于稀疏图(边相对较少),邻接矩阵会占用大量空间,因为大部分元素是 0。
- 插入和删除边的操作较慢,因为需要修改矩阵。
代码如下:
public class Graph <T>{
protected final int MAXSIZE=10;
protected final int MAX=999;
protected T[] V;
protected int[][] arcs;
protected int e;
protected int n;
public Graph(){
V=(T[])new Object[MAXSIZE];
arcs=new int[MAXSIZE][MAXSIZE];
}
public int LocateVex(T v){
int i;
for(i=0;i<n;i++){
if(V[i]==v){
return i;
}
}
return -1;
}
public void DisplayAdjMatrix(){
int i,j;
System.out.println("The Adjacency Matrix is:");
for(i=0;i<n;i++){
for(j=0;j<n;j++){
System.out.print(arcs[i][j]+" ");
}
System.out.println();
}
}
public void CreateAdj() {
int i, j, k;
T v1, v2;
Scanner sc = new Scanner(System.in);
System.out.println("请输入图的顶点数和边数:");
System.out.println("顶点数 n = ");
n = sc.nextInt();
System.out.println("边数 e = ");
e = sc.nextInt();
System.out.println("请输入图的顶点信息:");
String str = sc.next();
for (i = 0; i < n; i++) {
V[i] = (T)(Object)str.charAt(i);
}
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
arcs[i][j] = 0;
}
}
System.out.println("请输入图的边信息:");
for (k = 0; k < e; k++) {
System.out.println("请输入第" + (k + 1) + "条边的两个顶点:");
v1 = (T)(Object)sc.next().charAt(0);
v2 = (T)(Object)sc.next().charAt(0);
i = LocateVex(v1);
j = LocateVex(v2);
if (i >= 0 && j >= 0) {
arcs[i][j] = 1;
arcs[j][i] = 1;//如果需要有向图,去掉这句
} else {
System.out.println("输入的顶点信息不合法,请重新输入。");
k--; // 使得循环变量 k 不增加,重新输入当前边
}
}
}
public static void main(String[] args) {
Graph<Character> g=new Graph<Character>();
g.CreateAdj();
g.DisplayAdjMatrix();
}
}
邻接表是一种用链表来表示图的数据结构,每个顶点都关联一个链表,链表中存储与该顶点相邻的其他顶点。相比邻接矩阵,邻接表更适用于稀疏图(顶点较多,但边相对较少),因为它能够更有效地利用内存空间。以下是邻接表的基本概念和使用方法:
1. 基本概念:
- 顶点(Vertex): 图中的节点。
- 边(Edge): 顶点之间的连接线。
- 邻接表(Adjacency List): 用链表来表示图中顶点和相邻顶点的关系。
2. 邻接表的表示方法:
- 链表节点: 每个顶点都有一个关联的链表,链表中的节点表示与该顶点相邻的其他顶点。
- 数组: 用数组来存储所有顶点的链表头。
3. 邻接表的优点和缺点:
-
优点:
- 节省空间:对于稀疏图,邻接表比邻接矩阵更节省内存,因为只存储存在的边。
- 插入和删除边的操作较快,只需要对链表进行操作。
-
缺点:
- 查询两个顶点之间是否有边的操作可能较慢,需要遍历链表。
节点代码:
public class ArcNode {
int adjVex;
ArcNode nextArc;
int weight;
public ArcNode() {
adjVex = 0;
nextArc = null;
weight = 0;
}
}
public class VNode<T>{
T data;
ArcNode firstArc;
public VNode(){
data=null;
firstArc=null;
}
}
1. VNode
类:
VNode
类表示图中的顶点,每个顶点都关联一个邻接表。该类有两个主要成员变量:
data
: 存储顶点的信息,可以是任意类型的数据。firstArc
: 是一个指向ArcNode
类型的引用,指向该顶点的邻接表的第一个节点。
这个类定义了邻接表中顶点的结构,其中 data
存储顶点的值,而 firstArc
则指向与该顶点相邻的第一个节点,从而构成了链表。
2. ArcNode
类:
ArcNode
类表示邻接表中的链表节点,用于存储与某一顶点相邻的其他顶点的信息。该类有三个主要成员变量:
adjVex
: 存储相邻顶点的位置或索引。nextArc
: 是一个指向ArcNode
类型的引用,指向链表中的下一个节点。weight
: 存储边的权重(在这里未使用)。
这个类定义了邻接表中链表节点的结构,其中 adjVex
存储与当前顶点相邻的另一个顶点的位置,nextArc
则指向链表中下一个相邻节点,构成了链表结构。
图代码:
public class ALGraph<T>{
protected final int MAXSIZE=10;
protected VNode[] adjList;
int n,e;
public ALGraph(){
adjList=new VNode[MAXSIZE];
}
public void CreateLink(){
int i,j,k;
T v1,v2;
ArcNode s;
String str;
Scanner sc=new Scanner(System.in);
System.out.println("请输入图的顶点数和边数:");
System.out.println("顶点数 n = ");
n=sc.nextInt();
System.out.println("边数 e = ");
e=sc.nextInt();
System.out.println("请输入图的顶点信息:");
str=sc.next();
for(i=0;i<n;i++){
adjList[i]=new VNode<T>();
adjList[i].data=str.charAt(i);
adjList[i].firstArc=null;
}
System.out.println("请输入图的边的信息:");
for (k = 0; k < e; k++) {
System.out.println("请输入第" + (k + 1) + "条边的两个顶点:");
str = sc.next();
v1 = (T) (Object) str.charAt(0);
v2 = (T) (Object) str.charAt(1);
i = LocateVex(v1);
j = LocateVex(v2);
if (i>=0 && j>=0) {
s=new ArcNode();
s.adjVex=j;
s.nextArc=adjList[i].firstArc;
adjList[i].firstArc=s;
s=new ArcNode();//删除本行及下面部分得到有向图
s.adjVex=i;
s.nextArc=adjList[j].firstArc;
adjList[j].firstArc=s;
}
}
}
public int LocateVex(T v){
int i;
for(i=0;i<n;i++){
if(adjList[i].data==v){
return i;
}
}
return -1;
}
public void DisplayAdjList(){
int i;
ArcNode p;
System.out.println("The Adjacency List is:");
for(i=0;i<n;i++){
System.out.print(adjList[i].data+"->");
p=adjList[i].firstArc;
while(p!=null){
System.out.print(p.adjVex+" ");
p=p.nextArc;
}
System.out.println();
}
}
public static void main(String[] args) {
ALGraph<Character> g=new ALGraph<>();
g.CreateLink();
g.DisplayAdjList();
}
}