Вступление
Наряду с поиском по ширине, поиск по глубине является одним из двух основных методов обхода графа. Этот подход, хотя и отличается. Поиск в ширину (BFS) выглядит почти как начало с вершины и расширение процесса поиска уровень за уровнем. Это означает, что сначала мы получаем некоторую информацию обо всех преемниках данного узла, а затем мы идем дальше со следующим уровнем. Другими словами, BFS похожа на волну. Поиск в глубину основан на другом подходе, который может быть очень полезен в некоторых конкретных алгоритмах.
Оба метода могут быть полезны при решении разных задач.
обзор
Поиск в глубину — это алгоритм, который по заданному начальному и целевому узлу находит путь между ними. Мы также можем использовать DFS для обхода всех вершин графа, если граф связен.
Вся идея этого алгоритма заключается в том, чтобы как можно дальше от заданного начального узла искать цель. В случае, если мы добираемся до узла, который не имеет преемников, мы возвращаемся (обычно это делается рекурсивно), и мы продолжаем работу с последней вершиной, которая еще не посещена.
Итак, в основном у нас есть 3 шага:
- Подберите вершину, которая еще не посещена, и отметьте ее как посещенную;
- Перейти к первому не посещенному преемнику и отметить его как посещенное;
- Если все наследники вершины уже посещены или у нее нет наследников — вернитесь к ее родителю;
Код
Следующий код PHP реализует поиск в глубину. Ключевым моментом является рекурсия в методе deepFirst.
class Graph { protected $_len = 0; protected $_g = array(); protected $_visited = array(); public function __construct() { $this->_g = array( array(0, 1, 1, 0, 0, 0), array(1, 0, 0, 1, 0, 0), array(1, 0, 0, 1, 1, 1), array(0, 1, 1, 0, 1, 0), array(0, 0, 1, 1, 0, 1), array(0, 0, 1, 0, 1, 0), ); $this->_len = count($this->_g); $this->_initVisited(); } protected function _initVisited() { for ($i = 0; $i < $this->_len; $i++) { $this->_visited[$i] = 0; } } public function depthFirst($vertex) { $this->_visited[$vertex] = 1; echo $vertex . "\n"; for ($i = 0; $i < $this->_len; $i++) { if ($this->_g[$vertex][$i] == 1 && !$this->_visited[$i]) { $this->depthFirst($i); } } } } $g = new Graph(); // 2 0 1 3 4 5 $g->depthFirst(2);
сложность
Используя матрицу смежности, нам нужно пространство n 2 для графа с n вершинами. Мы также используем дополнительный массив для отметки посещенных вершин, который требует дополнительного пространства n ! Таким образом, сложность пространства равна O (n 2 ).
Когда дело доходит до сложности времени, поскольку у нас есть рекурсия, и мы пытаемся посетить все вершины на каждом шаге, время наихудшего случая еще раз O (n 2 )!
заявка
Этот алгоритм обхода графа может быть очень полезен при решении некоторых конкретных задач, таких как поиск самых коротких / самых длинных путей в графе. Хотя BFS и DFS не являются единственными методами обхода графа, они считаются двумя основными алгоритмами такого рода. Это важно для решения задач на основе графов.