图
1、图的一些基本概念
- 图:每个节点都可以有零个或多个前驱,也可以有零个或多个后继,也就是说,元素之间的关系是任意的。也可以称为多对多。
- 节点:组成图的重要部分
- 边:两个节点的连接
- 无向图:节点之间的连接没有方向
- 有向图:节点之间的连接有方向
- 带权图(网):权就是节点中的值
- 路径:一个节点到另一个节点所经过的路程
- 图的表示方法
- 邻接矩阵(用二维数组表示):表示图形之中节点间相邻关系的矩阵
- 邻接表(用数组+链表表示):数组之中存放了这个图中所有的节点,每一个数组又是一个链表的头节点,该链表表示这个节点与多少个节点有连接
- 图的深度优先遍历:先遍历每一个节点的第一个邻接节点,也就是纵向的遍历
- 步骤:
- 1、访问初始节点 i,并将该节点标记为已访问
- 2、查找节点 i的第一个邻接节点 j
- 3、若 j存在:
- 若 j未被访问,则对 j进行深度优先遍历,也就是把 j当作新的 i,递归
- 若 j被访问,则对 i的的其他邻接节点继续重复上述步骤
- 4、若 j不存在:则对 i的其他邻接节点继续重复上述步骤,若没有其他邻接节点,就结束该递归,回到上一层
- 5、直至所有的节点都已判断完毕,结束
- 图的广度优先遍历:先遍历一个节点的所有邻接节点,再去遍历其他节点,也就是横向的遍历,类似于一个分层搜索,需要先使用一个队列保持访问过的节点的顺序,以便于按照这个顺序访问这些节点的邻接节点。
- 步骤:
- 1、访问初始节点 i,并将该节点标记为已访问,该节点入队列
- 2、当队列为非空的时候,继续执行,否则算法结束(注意:这里的算法结束是指对当前 i的算法)
- 3、出队列,取得该队列的头部节点 j
- 4、查找节点 j的第一个邻接节点 k
- 1、若节点 k不存在,则回到 3
- 2、若节点 k存在,则:
- 1、若节点 k未被访问,则将 k标记为已访问,k入队列
- 2、查找节点 j的继节点 k的下一个邻接节点 k,回到步骤 5
2、一些常用的方法
public int getNumOfVertex() {
return vertexList.size();
}
public int getNumOfEdges() {
return numOfEdges;
}
public String getValueByIndex(int i) {
return vertexList.get(i);
}
public int getWeight(int v1, int v2) {
return edges[v1][v2];
}
public void showGraph() {
for (int[] link : edges) {
System.out.println(Arrays.toString(link));
}
}
public int getFirstNeighbor(int i) {
for (int j = 0; j < vertexList.size(); j++) {
if (edges[i][j] > 0) {
return j;
}
}
return -1;
}
public int getNextNeighbor(int v1, int v2) {
for (int j = v2 + 1; j < vertexList.size(); j++) {
if (edges[v1][j] > 0) {
return j;
}
}
return -1;
}
3、深度优先遍历
private void dfs(boolean[] isVisited, int i) {
System.out.print(getValueByIndex(i) + "->");
isVisited[i] = true;
int j = getFirstNeighbor(i);
while (j !=