mélységi keresés
Kiejtés
- IPA: [ ˈmeːjʃeːɡikɛrɛʃeːʃ]
Főnév
- (matematika, informatika, gráfelmélet, algoritmusok) A mélységi keresés (DFS) egy gráfkeresési algoritmus, amely egy gráf csúcsait mélységi sorrendben járja be. Az algoritmus elindul egy kezdőcsúcsból, és addig halad egy irányba, amíg már nincs további lehetőség. Ezután visszalép az előző csúcsra, és folytatja a keresést.
Algoritmus működése
- Kezdés:
- A kiinduló csúcsot jelöljük látogatottként.
- Lépés:
- Haladjunk tovább egy szomszédos csúcs felé, amelyet még nem látogattunk meg.
- Visszalépés:
- Ha elértük egy út végét (nincs látogatatlan szomszédos csúcs), térjünk vissza az előző csúcsra.
- Ismétlés:
- Addig folytatjuk, amíg minden elérhető csúcsot be nem jártunk.
Adatszerkezet:
- A DFS tipikusan rekurzióval vagy egy verem (stack) adatszerkezettel valósítható meg.
Tulajdonságok
- Időkomplexitás: (O(V + E)), ahol (V) a csúcsok száma, (E) az élek száma.
- Térkomplexitás:
- Rekurzív megvalósítás: (O(V)) a rekurzív hívások miatt.
- Iteratív megvalósítás: (O(V)) a verem miatt.
- Alkalmazások:
- Összefüggő komponensek meghatározása.
- Körök észlelése.
- Topologikus rendezés.
- Útvonal keresése.
Pszeudokód
Rekurzív változat
DFS(G, v): jelöld v-t látogatottként minden szomszéd u esetén: ha u nincs látogatottként jelölve: DFS(G, u)
Iteratív változat
DFS(G, v): verem = üres verem.push(v) amíg verem nem üres: u = verem.pop() ha u nincs látogatottként jelölve: jelöld u-t látogatottként minden szomszéd w esetén: ha w nincs látogatottként jelölve: verem.push(w)
Python implementáció
Rekurzív változat
def dfs_recursive(graph, node, visited):
if node not in visited:
print(node, end=" ")
visited.add(node)
for neighbor in graph[node]:
dfs_recursive(graph, neighbor, visited)
# Példa gráf
graph = {
0: [1, 2],
1: [0, 3, 4],
2: [0],
3: [1],
4: [1, 5],
5: [4]
}
visited = set()
print("DFS rekurzívan:")
dfs_recursive(graph, 0, visited)
Iteratív változat
def dfs_iterative(graph, start):
visited = set()
stack = [start]
while stack:
node = stack.pop()
if node not in visited:
print(node, end=" ")
visited.add(node)
# Hozzáadjuk a szomszédokat a veremhez (fordított sorrendben a logikus sorrendért)
for neighbor in reversed(graph[node]):
if neighbor not in visited:
stack.append(neighbor)
# Példa gráf
graph = {
0: [1, 2],
1: [0, 3, 4],
2: [0],
3: [1],
4: [1, 5],
5: [4]
}
print("DFS iteratívan:")
dfs_iterative(graph, 0)
Kimenet mindkét esetben (a példagráftól függően):
DFS rekurzívan: 0 1 3 4 5 2 DFS iteratívan: 0 1 3 4 5 2
C++ implementáció
Rekurzív változat
#include <iostream>
#include <vector>
#include <unordered_set>
using namespace std;
void dfs_recursive(const vector<vector<int>>& graph, int node, unordered_set<int>& visited) {
if (visited.find(node) == visited.end()) {
cout << node << " ";
visited.insert(node);
for (int neighbor : graph[node]) {
dfs_recursive(graph, neighbor, visited);
}
}
}
int main() {
vector<vector<int>> graph = {
{1, 2}, {0, 3, 4}, {0}, {1}, {1, 5}, {4}
};
unordered_set<int> visited;
cout << "DFS rekurzívan:" << endl;
dfs_recursive(graph, 0, visited);
return 0;
}
Iteratív változat
#include <iostream>
#include <vector>
#include <stack>
#include <unordered_set>
using namespace std;
void dfs_iterative(const vector<vector<int>>& graph, int start) {
unordered_set<int> visited;
stack<int> s;
s.push(start);
while (!s.empty()) {
int node = s.top();
s.pop();
if (visited.find(node) == visited.end()) {
cout << node << " ";
visited.insert(node);
for (auto it = graph[node].rbegin(); it != graph[node].rend(); ++it) {
if (visited.find(*it) == visited.end()) {
s.push(*it);
}
}
}
}
}
int main() {
vector<vector<int>> graph = {
{1, 2}, {0, 3, 4}, {0}, {1}, {1, 5}, {4}
};
cout << "DFS iteratívan:" << endl;
dfs_iterative(graph, 0);
return 0;
}
Kimenet mindkét esetben:
DFS rekurzívan: 0 1 3 4 5 2 DFS iteratívan: 0 1 3 4 5 2
Összegzés
A mélységi keresés (DFS) hatékony és egyszerű módszer gráfok bejárására. Széles körben alkalmazzák összefüggő komponensek meghatározására, körök keresésére, topologikus rendezésre és útvonalak felfedezésére. A rekurzív változat olvashatóbb, de nagy gráfok esetén az iteratív megközelítés jobb, mert elkerüli a túlmély rekurzív hívásokat.
Fordítások
- angol: depth-first search (en)
- orosz: поиск в глубину (ru) (poisk v glubinu)
- mélységi keresés - Értelmező szótár (MEK)
- mélységi keresés - Etimológiai szótár (UMIL)
- mélységi keresés - Szótár.net (hu-hu)
- mélységi keresés - DeepL (hu-de)
- mélységi keresés - Яндекс (hu-ru)
- mélységi keresés - Google (hu-en)
- mélységi keresés - Helyesírási szótár (MTA)
- mélységi keresés - Wikidata
- mélységi keresés - Wikipédia (magyar)