Hloubkové první vyhledávání nebo DFS pro graf
Depth First Traversal (nebo DFS) pro graf je podobný Hloubka První přejezd stromu. Jediný háček je v tom, že na rozdíl od stromů mohou grafy obsahovat cykly (uzel lze navštívit dvakrát). Chcete-li se vyhnout zpracování uzlu více než jednou, použijte booleovské navštívené pole. Graf může mít více než jedno procházení DFS.
Příklad:
Doporučená praxe DFS of Graph Vyzkoušejte to!Vstup: n = 4, e = 6
0 -> 1, 0 -> 2, 1 -> 2, 2 -> 0, 2 -> 3, 3 -> 3
Výstup: DFS z vrcholu 1 : 1 2 0 3
Vysvětlení:
Diagram DFS:![]()
Příklad 1
Vstup: n = 4, e = 6
2 -> 0, 0 -> 2, 1 -> 2, 0 -> 1, 3 -> 3, 1 -> 3
Výstup: DFS z vrcholu 2 : 2 0 1 3
Vysvětlení:
Diagram DFS:![]()
Příklad 2
Jak DFS funguje?
Hloubkové vyhledávání je algoritmus pro procházení nebo prohledávání stromových nebo grafových datových struktur. Algoritmus začíná v kořenovém uzlu (v případě grafu vybere nějaký libovolný uzel jako kořenový uzel) a prozkoumá co nejdále podél každé větve, než se vrátí zpět.
Pojďme pochopit fungování Hloubka první hledání s pomocí následující ilustrace:
Krok 1: Zpočátku jsou zásobník a navštívená pole prázdná.
Zásobník a navštívená pole jsou zpočátku prázdná.
Krok 2: Navštivte 0 a vložte její sousední uzly, které ještě nebyly navštíveny, do zásobníku.
Navštivte uzel 0 a vložte jeho sousední uzly (1, 2, 3) do zásobníku
Krok 3: Nyní je uzel 1 na vrcholu zásobníku, takže navštivte uzel 1, vyndejte ho ze zásobníku a vložte všechny jeho sousední uzly, které nejsou navštěvovány do zásobníku.
Navštivte uzel 1
Krok 4: Nyní, Uzel 2 nahoře na hromádce, takže navštivte uzel 2 a vyndejte ho z hromádky a vložte všechny jeho sousední uzly, které nejsou navštíveny (tj. 3, 4) do hromádky.
Navštivte uzel 2 a vložte jeho nenavštívené sousední uzly (3, 4) do zásobníku
Krok 5: Nyní je uzel 4 nahoře na hromádce, takže navštivte uzel 4, vyndejte ho z hromádky a umístěte všechny jeho sousední uzly, které nejsou navštíveny.
Navštivte uzel 4
Krok 6: Nyní je uzel 3 nahoře na hromádce, takže navštivte uzel 3, vyndejte ho z hromádky a vložte všechny jeho sousední uzly, které nejsou navštíveny.
Navštivte uzel 3
Nyní se Stack vyprázdní, což znamená, že jsme navštívili všechny uzly a naše procházení DFS končí.
Níže je uvedena implementace výše uvedeného přístupu:
C++
// C++ program to print DFS traversal from> // a given vertex in a given graph> #include> using> namespace> std;> // Graph class represents a directed graph> // using adjacency list representation> class> Graph {> public> :> > map <> int> ,> bool> >navštívil;> > map <> int> , list <> int> >> adj;> > // Function to add an edge to graph> > void> addEdge(> int> v,> int> w);> > // DFS traversal of the vertices> > // reachable from v> > void> DFS(> int> v);> };> void> Graph::addEdge(> int> v,> int> w)> {> > // Add w to v’s list.> > adj[v].push_back(w);> }> void> Graph::DFS(> int> v)> {> > // Mark the current node as visited and> > // print it> > visited[v] => true> ;> > cout < < v < <> ;> > // Recur for all the vertices adjacent> > // to this vertex> > list <> int> >::iterátor i;> > for> (i = adj[v].begin(); i != adj[v].end(); ++i)> > if> (!visited[*i])> > DFS(*i);> }> // Driver code> int> main()> {> > // Create a graph given in the above diagram> > Graph g;> > g.addEdge(0, 1);> > g.addEdge(0, 2);> > g.addEdge(1, 2);> > g.addEdge(2, 0);> > g.addEdge(2, 3);> > g.addEdge(3, 3);> > cout < <> 'Following is Depth First Traversal'> > ' (starting from vertex 2)
'> ;> > // Function call> > g.DFS(2);> > return> 0;> }> // improved by Vishnudev C> |
Jáva
// Java program to print DFS traversal> // from a given graph> import> java.io.*;> import> java.util.*;> // This class represents a> // directed graph using adjacency> // list representation> class> Graph {> > private> int> V;> > // Array of lists for> > // Adjacency List Representation> > private> LinkedList adj[];> > // Constructor> > @SuppressWarnings> (> 'unchecked'> ) Graph(> int> v)> > {> > V = v;> > adj => new> LinkedList[v];> > for> (> int> i => 0> ; i adj[i] = new LinkedList(); } // Function to add an edge into the graph void addEdge(int v, int w) { // Add w to v's list. adj[v].add(w); } // A function used by DFS void DFSUtil(int v, boolean visited[]) { // Mark the current node as visited and print it visited[v] = true; System.out.print(v + ' '); // Recur for all the vertices adjacent to this // vertex Iterator i = adj[v].listIterator(); while (i.hasNext()) { int n = i.next(); if (!visited[n]) DFSUtil(n, visited); } } // The function to do DFS traversal. // It uses recursive DFSUtil() void DFS(int v) { // Mark all the vertices as // not visited(set as // false by default in java) boolean visited[] = new boolean[V]; // Call the recursive helper // function to print DFS // traversal DFSUtil(v, visited); } // Driver Code public static void main(String args[]) { Graph g = new Graph(4); g.addEdge(0, 1); g.addEdge(0, 2); g.addEdge(1, 2); g.addEdge(2, 0); g.addEdge(2, 3); g.addEdge(3, 3); System.out.println( 'Following is Depth First Traversal ' + '(starting from vertex 2)'); // Function call g.DFS(2); } } // This code is contributed by Aakash Hasija> |
Python3
# Python3 program to print DFS traversal> # from a given graph> from> collections> import> defaultdict> # This class represents a directed graph using> # adjacency list representation> class> Graph:> > # Constructor> > def> __init__(> self> ):> > # Default dictionary to store graph> > self> .graph> => defaultdict(> list> )> > > # Function to add an edge to graph> > def> addEdge(> self> , u, v):> > self> .graph[u].append(v)> > > # A function used by DFS> > def> DFSUtil(> self> , v, visited):> > # Mark the current node as visited> > # and print it> > visited.add(v)> > print> (v, end> => )> > # Recur for all the vertices> > # adjacent to this vertex> > for> neighbour> in> self> .graph[v]:> > if> neighbour> not> in> visited:> > self> .DFSUtil(neighbour, visited)> > > # The function to do DFS traversal. It uses> > # recursive DFSUtil()> > def> DFS(> self> , v):> > # Create a set to store visited vertices> > visited> => set> ()> > # Call the recursive helper function> > # to print DFS traversal> > self> .DFSUtil(v, visited)> # Driver's code> if> __name__> => => '__main__'> :> > g> => Graph()> > g.addEdge(> 0> ,> 1> )> > g.addEdge(> 0> ,> 2> )> > g.addEdge(> 1> ,> 2> )> > g.addEdge(> 2> ,> 0> )> > g.addEdge(> 2> ,> 3> )> > g.addEdge(> 3> ,> 3> )> > print> (> 'Following is Depth First Traversal (starting from vertex 2)'> )> > > # Function call> > g.DFS(> 2> )> # This code is contributed by Neelam Yadav> |
C#
// C# program to print DFS traversal> // from a given graph> using> System;> using> System.Collections.Generic;> // This class represents a directed graph> // using adjacency list representation> class> Graph {> > private> int> V;> > // Array of lists for> > // Adjacency List Representation> > private> List <> int> >[] adj;> > // Constructor> > Graph(> int> v)> > {> > V = v;> > adj => new> List <> int> >[ v ];> > for> (> int> i = 0; i adj[i] = new List |
Javascript
// Javascript program to print DFS> // traversal from a given> // graph> // This class represents a> // directed graph using adjacency> // list representation> class Graph> {> > > // Constructor> > constructor(v)> > {> > this> .V = v;> > this> .adj => new> Array(v);> > for> (let i = 0; i this.adj[i] = []; } // Function to add an edge into the graph addEdge(v, w) { // Add w to v's list. this.adj[v].push(w); } // A function used by DFS DFSUtil(v, visited) { // Mark the current node as visited and print it visited[v] = true; console.log(v + ' '); // Recur for all the vertices adjacent to this // vertex for(let i of this.adj[v].values()) { let n = i if (!visited[n]) this.DFSUtil(n, visited); } } // The function to do DFS traversal. // It uses recursive // DFSUtil() DFS(v) { // Mark all the vertices as // not visited(set as // false by default in java) let visited = new Array(this.V); for(let i = 0; i |
Výstup
Following is Depth First Traversal (starting from vertex 2) 2 0 1 3
Analýza složitosti prvního vyhledávání hloubky:
- Časová složitost: O(V + E), kde V je počet vrcholů a E je počet hran v grafu.
- Pomocný prostor: O(V + E), protože je vyžadováno další navštívené pole velikosti V a velikost zásobníku pro iterativní volání funkce DFS.