「这是我参与2022首次更文挑战的第24天,活动详情查看:2022首次更文挑战」。
图(Graph)
由顶点集合和边集组成。分为有向图、无向图、权重图。
-
无向图:每个顶点和其他顶点无方向的连接。
-
有向图:每个顶点和其他顶点有方向的连接。
-
权重图:每条相连线存在各自的权重。
有向图的实现
可以利用邻接矩阵来实现。
| n\m | 一 | 二 | 三 | 四 |
|---|---|---|---|---|
| 一 | 0 | 1 | 1 | 0 |
| 二 | 0 | 0 | 1 | 1 |
| 三 | 0 | 0 | 0 | 1 |
| 四 | 0 | 0 | 0 | 0 |
矩阵中0表示n点到m点没有边,1表示n点到m点存在有向边。
也可以利用链表来实现
代码实现(链表)
public class ListGraph{
ArraryList<ArraryList<Integer>>graphs;
public ListGraph(int v){
graphs = new ArrayList<>(v);
for(int i = 0;i < V;i ++){
graphs.add(new ArrayList<>());
}
}
// 尾插法插入节点
public void addEdge(int start,int end){
graphs.get(start).add(end);
}
// 删除节点
public void removeEdge(int start,int end){
graphs.get(start).remove((Integer)end);
}
}
图的遍历
DFS(深度优先遍历)
- 假设初始状态所有的顶点都未被访问,然后从每一个顶点v出发,先访问该顶点
- 然后依次从他未访问的邻接点出发,深度优先遍历图,直到图中所有和v相通的顶点都被访问到。
- 遍历完后如果还有其他顶点未被访问到,则另选一个未被访问的顶点作为起始点。
- 重复上述过程,直到所有顶点都被访问完为止。
代码
/**图的实体类**/
public class ListGraph{
ArrayList<ArrayList<Integer>>graphs;
public ListGraph(int v){
graphs = new ArrayList<>(v);
for(int i = 0;i < v;i ++){
graphs.add(new ArrayList<>());
}
}
// 尾插法插入节点
public void addEdge(int start,int end){
graphs.get(start).add(end);
}
// 删除节点
public void removeEdge(int start,int end){
graphs.get(start).remove((Integer)end);
}
}
/**实现类**/
class GraphTraversal{
// 之前实现的图
ListGraph graph;
// 标记访问过的节点
boolean[] visited;
public GraphTraversal(ListGraph listGraph){
this.graph = listGraph;
visited = new boolean[listGraph.graphs.size()];
}
public void DFSTraversal(int v) {
if (visited[v]) {
return;
}
visited[v] = true;
System.out.print(v + "->");
Iterator<Integer> neighbors = graph.graphs.get(v).listIterator();
while (neighbors.hasNext()) {
int nextNode = neighbors.next();
if (!visited[nextNode]) {
DFSTraversal(nextNode);
}
}
}
public void DFS(){
for(int i = 0; i < graph.graphs.size();i++){
if(!visited[i]){
DFSTraversal(i);
}
}
}
}
BFS(广度优先遍历)
- 从图中的某一点出发,在访问了v之后依次访问v的各个没有访问到的邻接点。
- 然后分别从这些邻接点出发依次访问他们的邻接点,使得先被访问的邻接点先与后被访问顶点的邻接点被访问,直到图中所有已被访问的顶点的邻接点都被访问到。
- 如果此时图中尚有顶点未被访问,则需要另选一个未曾被访问到的顶点作为新的起始点,重复上述过程。
代码
/**图的实体类**/
public class ListGraph{
ArrayList<ArrayList<Integer>>graphs;
public ListGraph(int v){
graphs = new ArrayList<>(v);
for(int i = 0;i < v;i ++){
graphs.add(new ArrayList<>());
}
}
// 尾插法插入节点
public void addEdge(int start,int end){
graphs.get(start).add(end);
}
// 删除节点
public void removeEdge(int start,int end){
graphs.get(start).remove((Integer)end);
}
}
/**实现类**/
class GraphTraversal{
/** 之前实现的图*/
ListGraph graph;
/** 标记访问过的节点*/
boolean[] visited;
public GraphTraversal(ListGraph listGraph){
this.graph = listGraph;
visited = new boolean[listGraph.graphs.size()];
}
public void BFSTraversal(int v){
Deque<Integer>queue = new ArrayDeque<>();
visited[v] = true;
queue.offerFirst(v);
while(queue.size() != 0){
Integer cur = queue.pollFirst();
System.out.println(cur+"->");
ListIterator<Integer> neighbors = graph.graphs.get(cur).listIterator();
int nextNode = neighbors.next();
if(!visited[nextNode]){
queue.offerLast(nextNode);
visited[nextNode] = true;
}
}
}
public void BFS(){
for (int i = 0; i < graph.graphs.size(); i++) {
if (!visited[i]){
BFSTraversal(i);
}
}
}
}