图基本介绍:
为什么要有图?
1) 前面我们学了线性表和树
2) 线性表局限于一个直接前驱和一个直接后继的关系
3) 树也只能有一个直接前驱也就是父节点
4) 当我们需要 表示多对多的关系时, 这里我们就用到了图
图的举例说明:
图是一种数据结构,其中结点可以具有零个或多个相邻元素。两个结点之间的连接称为边。 结点也可以称为顶点。如图:
图的常用概念:
1) 顶点(vertex)
2) 边(edge)
3) 路径
4) 无向图(下图)
5) 有向图
6) 带权图
图的表示方法:
图的表示方式有两种:二维数组表示(邻接矩阵);链表表示(邻接表)。
邻接矩阵:
邻接矩阵是表示图形中顶点之间相邻关系的矩阵,对于 n 个顶点的图而言,邻接矩阵就是n*n的二维矩阵,可以用矩阵中的值的不同来表示不同顶点之间的关系。
如同:
邻接表:
1) 邻接矩阵需要为每个顶点都分配 n 个边的空间,其实有很多边都是不存在,会造成空间的一定浪费.
2) 邻接表的实现只考虑存在的边,不考虑不存在的边。因此没有空间浪费,邻接表由数组+链表组成
如图:
以上就是关于图的基本介绍,下面实现邻接矩阵来表示下图.
代码如下:
import java.util.ArrayList;
import java.util.LinkedList;
/**
* 实现一个基本的无向图
*/
public class Graph {
//存储顶点的集合
private ArrayList<String> vertexList = new ArrayList<>();
//存储图对应的矩阵,保存边的关系
private int[][] edges;
//表示边的数目
private int numOfEdges;
//标志该顶点是否被访问过了
private boolean[] isVisited;
//创建一个队列
private LinkedList<Integer> queue = new LinkedList<>();
public Graph(int vertexSize) {
edges = new int[vertexSize][vertexSize];
isVisited = new boolean[vertexSize];
}
public Graph() {
}
//添加顶点
public void insertVertex(String vertex){
vertexList.add(vertex);
}
/** 添加边
*
* @param v1 表示第一个顶点对应的下标
* @param v2 表示第二个顶点对应的下标
* @param weight 表示两个顶点之间的关系,0表示不直连,1表示直连
*/
public void insertEdge(int v1,int v2,int weight){
edges[v1][v2] = weight;
//因为是无向图,所以还需要反过来存储
edges[v2][v1] = weight;
if (weight == 1) {
//将边的数量++
numOfEdges++;
}
}
//获取顶点的个数
public int getNumOfVertex(){
return vertexList.size();
}
//获取边的条数
public int getNumOfEdges(){
return numOfEdges;
}
//显示图形
public void showGraph(){
for (int i = 0; i < edges.length; i++) {
for (int j = 0; j < edges[i].length; j++) {
System.out.print(edges[i][j] + " ");
}
System.out.println();
}
return ;
}
//根据索引来获取顶点的值
public String getValueByIndex(int index){
return vertexList.get(index);
}
//根据两个顶点的下标来获取他们之间的权值
public int getWeight(int v1,int v2){
return edges[v1][v2];
}
}
测试无向图:
public class GraphTest {
public static void main(String[] args) {
//创建一个数组
String[] vertex = {"A","B","C","D","E"};
//创建一个图
Graph graph = new Graph(vertex.length);
//存储顶点的值
for (int i = 0; i < vertex.length; i++) {
graph.insertVertex(vertex[i]);
}
//添加图之前的关系,1表示直连,0表示没有直连
// A-B A-C B-C B-D B-E
graph.insertEdge(0,1,1);
graph.insertEdge(0,2,1);
graph.insertEdge(1,2,1);
graph.insertEdge(1,3,1);
graph.insertEdge(1,4,1);
//显示图形
graph.showGraph();
}
}