写在前面
图
- 处理多对多的关系
- 边,两个节点之间的关系;节点,也可以叫做顶点
- 无向图,顶点之间连接没有方向
- 有向图,顶点之间有方向
- 带权图,边带权值
- 表现方式,邻接矩阵(二维数组),
1
表示连通;邻接表(数组+链表),该条链表中有的元素,代表跟这个点连通,比如arr[0]
的链表元素为1,2,3,4
,表示0跟这四个点都连通
邻接矩阵实现图
public class Graph {
private ArrayList<String> vertexList;
private int[][] edges;
private int numOfEdges;
public Graph(int n) {
edges = new int[n][n];
vertexList = new ArrayList<>();
numOfEdges = 0;
}
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[] edge : edges) {
System.out.println(Arrays.toString(edge));
}
}
public void insertVertex(String vertex) {
vertexList.add(vertex);
}
public void insertEdge(int v1, int v2, int weight) {
edges[v1][v2] = weight;
edges[v2][v1] = weight;
numOfEdges ++;
}
}
图的深度优先遍历
- 纵向
- Depth First Search,DFS,从初始访问节点出发,初始访问节点可能有多个邻接节点;首先访问第一个节点,访问第一个节点的邻接点,再以这个邻接点访问下一个节点;优先向纵向挖掘深入;递归过程
- 得到第一个邻接节点的下标
public int getFirstNeighbor(int index) {
for (int i = 0; i < vertexList.size(); i++) {
if (edges[index][i] == 1) {
return i;
}
}
return -1;
}
public int getNextNeighbor(int v1, int v2) {
for (int i = v2 + 1; i < vertexList.size(); i++) {
if (edges[v1][i] == 1) {
return i;
}
}
return -1;
}
private void dfs(boolean[] isVisited, int i) {
System.out.print(getValueByIndex(i) + " -> ");
isVisited[i] = true;
int w = getFirstNeighbor(i);
while (w != -1) {
if (!isVisited[w]) {
dfs(isVisited, w);
}
w = getNextNeighbor(i,w);
}
}
- 对dfs进行重载,遍历所有节点,进行dfs;输出的点不在输出,如果是最后一个点,由于是双向的,那么他一定被前面的点扫描输出过了;如果是单独的一个点,也会被扫描到
public void dfs() {
for (int i = 0; i < getNumOfVertex(); i++) {
if (!isVisited[i]) {
dfs(isVisited, i);
}
}
}
图的广度优先遍历
- 横向,一层一层
- Broad First Search,使用一个队列保持访问过的节点的顺序,按这个顺序来访问这些节点的邻接节点
- 先把一个点的所有连通点找到
- 广度优先遍历
public void bfs(boolean[] isVisited, int i) {
int u;
int w;
LinkedList<Integer> queue = new LinkedList<>();
System.out.print(getValueByIndex(i) + " -> ");
isVisited[i] = true;
queue.addLast(i);
while (!queue.isEmpty()) {
u = queue.removeFirst();
w = getFirstNeighbor(u);
while (w != -1) {
if (!isVisited[w]) {
System.out.print(getValueByIndex(w) + " -> ");
isVisited[w] = true;
queue.addLast(w);
}
w = getNextNeighbor(u,w);
}
}
}
public void bfs() {
for (int i = 0; i < getNumOfVertex(); i++) {
if (!isVisited[i]) {
bfs(isVisited,i);
}
}
}