[Notas de algoritmos] Introducción a la estructura de gráficos y gráficos DFS y BFS

Prefacio: este artículo presentará cómo lidiar con la estructura del gráfico en la entrevista, y también presentará brevemente BFS y DFS

1. Introducción básica a los gráficos

concepto basico:

  • Un grafo consta de un conjunto de vértices y un conjunto de aristas
  • Aunque existen conceptos de gráficos dirigidos y gráficos no dirigidos, en realidad se pueden expresar mediante gráficos dirigidos.
  • Los bordes pueden tener pesos

La estructura del gráfico:

  • método de lista de adyacencia
  • Método de matriz de adyacencia
  • Hay muchas otras formas

Cómo resolver las preguntas de la entrevista gráfica: el algoritmo gráfico no es difícil, pero es muy complicado escribir el código, y el costo de codificación es relativamente alto, por lo que puede tratar las preguntas de la entrevista gráfica de las siguientes maneras

  • Primero, use su forma más competente para realizar la expresión de la estructura del gráfico
  • Implemente todos los algoritmos gráficos de uso común como plantillas en una estructura familiar
  • Convierta la estructura gráfica proporcionada por la pregunta de la entrevista en una estructura gráfica con la que esté familiarizado y luego llame a la plantilla o reescríbala (haga un adaptador)

2. Implementación del gráfico

Código de implementación:

  • Implementación de la estructura de puntos

    import java.util.ArrayList;
    
    // 点结构的描述
    public class Node {
          
          
    	// 该点的值
    	public int value;
    	// 该点的入度数
    	public int in;
    	// 该点的出度数
    	public int out;
    	// 该点的相邻点(指该点指向的点)
    	public ArrayList<Node> nexts;
    	// 该点的相邻边(指该点指向的边)
    	public ArrayList<Node> edges;
    
    	public Node(int value) {
          
          
    		this.value = value;
    		in = 0;
    		out = 0;
    		nexts = new ArrayList<>();
    		edges = new ArrayList<>();
    	}
    }
    
  • Implementación de estructura de borde

    // 边结构的描述
    public class Edge {
          
          
    	// 边的权重
    	public int weight;
    	// 入边节点
    	public Node from;
    	// 出边节点
    	public Node to;
    
    	public Edge(int weight, Node from, Node to) {
          
          
    		this.weight = weight;
    		this.from = from;
    		this.to = to;
    	}
    }
    
  • Implementación de estructura gráfica

    import java.util.HashMap;
    import java.util.HashSet;
    
    // 图的描述
    public class Graph {
          
          
    	// 点的集合,Integer 表示节点的值,先有值,再创建节点
    	public HashMap<Integer, Node> nodes;
    	// 边的集合
    	public HashSet<Edge> edges;
    
    	public Graph() {
          
          
    		nodes = new HashMap<>();
    		edges = new HashSet<>();
    	}
    }
    

Estructura del diagrama de preguntas comunes de la entrevista:

  • Representado por una matriz bidimensional, cada matriz unidimensional tiene tres valores
  • El primer valor representa el peso del borde.
  • El segundo valor representa el nodo inicial del borde.
  • El tercer valor representa el nodo de destino del borde.

Supongamos que una representación de matriz existente es así: { {3, 0, 7}, {5, 1, 2}, {6, 2, 7}}, que se ajusta a la estructura de la figura anterior, entonces se representa como sigue

imagen

Cuando entrevistamos un grafo con esta estructura, podemos utilizar la estructura del grafo que hemos definido anteriormente para representarlo, por lo que solo nos falta hacer otro proceso de adaptación

Código de adaptación:

public class Create {
    
    
	
	public static Graph createGraph(int[][] matrix) {
    
    
		Graph graph=new Graph();
		for(int i=0;i<matrix.length;i++) {
    
    
			// 边的权重
			int weight=matrix[i][0];
			// 出发节点的值
			int from=matrix[i][1];
			// 目的节点的值
			int to=matrix[i][2];
			// 如果该图中还没有包含该节点,则将节点入图
			if(!graph.nodes.containsKey(from)) {
    
    
				graph.nodes.put(from, new Node(from));
			}
			if(!graph.nodes.containsKey(to)) {
    
    
				graph.nodes.put(to, new Node(to));
			}
			Node fromNode=graph.nodes.get(from);
			Node toNode=graph.nodes.get(to);
			Edge edge=new Edge(weight,fromNode,toNode);
			fromNode.out++;
			toNode.in++;
			fromNode.nexts.add(toNode);
			fromNode.edges.add(edge);
			graph.edges.add(edge);
		}
		return graph;
	}
}

3. BFS

método BFS:

Extraiga el nodo de nivel superior del gráfico, utilizando unConjunto de colecciónregistre el nodo, luego ingrese el nodo encola. Cuando lo extraigamos de la cola, coloque su nodo adyacente (nodo puntiagudo) en la cola, pero primero debemos determinar si el nodo adyacente está registrado en el conjunto; si está registrado, no se procesará; si lo está no registrado, registre y ponga en cola el nodo. Luego repita la operación justo ahora, atravesando cada capa

Plantilla de método:

import java.util.HashSet;
import java.util.LinkedList;
import java.util.Queue;

public class BFS {
    
    
	// BFS 需要有一个头节点
	public static void bfs(Node start) {
    
    
		if (start == null) {
    
    
			return;
		}
		Queue<Node> queue = new LinkedList<>();
		HashSet<Node> set = new HashSet<>();
		queue.add(start);
		set.add(start);
		while (!queue.isEmpty()) {
    
    
			Node node = queue.poll();
			System.out.println(node.value);
			for (Node cur : node.nexts) {
    
    
				if (!set.contains(cur)) {
    
    
					set.add(cur);
					queue.add(cur);
				}
			}
		}
	}
}

4. DFS

Método DFS:

Un camino va hasta el final, pero no se puede formar un bucle, cuando llega al final, vuelve al nodo anterior, si no hay otra forma de llegar al nodo, sigue subiendo. Cuando un nodo tiene otras rutas, primero determine si el nuevo nodo se imprimió y continúe subiendo hasta que se encuentre un nuevo nodo y no se haya impreso. Cuando finalmente se devuelve el nodo principal, finaliza el recorrido de profundidad. que usoConjunto de colecciónpara marcar si el nodo ha sido caminado o impreso, usepilapara almacenar el nodo de la ruta transversal actual

Plantilla de método:

import java.util.HashSet;
import java.util.Stack;

public class DFS {
    
    

	public static void dfs(Node node) {
    
    
		if (node == null) {
    
    
			return;
		}
		Stack<Node> stack = new Stack<>();
		HashSet<Node> set = new HashSet<>();
		stack.add(node);
		set.add(node);
		// 在入栈时就进行打印
		System.out.println(node.value);
		while (!stack.isEmpty()) {
    
    
			Node cur = stack.pop();
			for (Node next : cur.nexts) {
    
    
				if (!set.contains(next)) {
    
    
					stack.add(cur);
					stack.add(next);
					set.add(next);
					System.out.println(next.value);
					break;
				}
			}
		}
	}
}

Supongo que te gusta

Origin blog.csdn.net/weixin_51367845/article/details/123243184
Recomendado
Clasificación