Weapon used by ships or aircraft to attack submerged submarines. Developed by the British in World War I for use against German submarines, it consisted of a canister filled with explosives and dropped off the stern of a ship near a submerged submarine. It rarely exploded close enough to sink the submarine, but its shock waves loosened the submarine's joints and damaged its instruments, forcing it to the surface, where naval gunfire could finish it off. Modern depth charges can be fired as far as 2,000 yards (1,800 m) from a ship's deck or launched from aircraft. Atomic depth charges have a nuclear warhead and a vastly increased killing radius.
Learn more about depth charge with a free trial on Britannica.com.
Formally, DFS is an uninformed search that progresses by expanding the first child node of the search tree that appears and thus going deeper and deeper until a goal node is found, or until it hits a node that has no children. Then the search backtracks, returning to the most recent node it hadn't finished exploring. In a non-recursive implementation, all freshly expanded nodes are added to a LIFO stack for exploration.
Space complexity of DFS is much lower than BFS (breadth-first search). It also lends itself much better to heuristic methods of choosing a likely-looking branch. Time complexity of both algorithms are proportional to the number of vertices plus the number of edges in the graphs they traverse (O(|V| + |E|)).
When searching large graphs that cannot be fully contained in memory, DFS suffers from non-termination when the length of a path in the search tree is infinite. The simple solution of "remember which nodes I have already seen" doesn't always work because there can be insufficient memory. This can be solved by maintaining an increasing limit on the depth of the tree, which is called iterative deepening depth-first search.
For the following graph:
a depth-first search starting at A, assuming that the left edges in the shown graph are chosen before right edges, and assuming the search remembers previously-visited nodes and will not repeat them (since this is a small graph), will visit the nodes in the following order: A, B, D, F, E, C, G.
Performing the same search without remembering previously visited nodes results in visiting nodes in the order A, B, D, F, E, A, B, D, F, E, etc. forever, caught in the A, B, D, F, E cycle and never reaching C or G.
Iterative deepening prevents this loop and will reach the following nodes on the following depths, assuming it proceeds left-to-right as above:
(Note that iterative deepening has now seen C, when a conventional depth-first search did not.)
(Note that it still sees C, but that it came later. Also note that it sees E via a different path, and loops back to F twice.)
For this graph, as more depth is added, the two cycles "ABFE" and "AEFB" will simply get longer before the algorithm gives up and tries another branch.
The most natural result of a depth first search of a graph (if it is considered as a function rather than a procedure) is a spanning tree of the vertices reached during the search. Based on this spanning tree, the edges of the original graph can be divided into three classes: forward edges, which point from a node of the tree to one of its descendants, back edges, which point from a node to one of its ancestors, and cross edges, which do neither. Sometimes tree edges, edges which belong to the spanning tree itself, are classified separately from forward edges. It can be shown that if the graph is undirected then all of its edges are tree edges or back edges.
It is also possible to use the depth-first search to linearly order the vertices (or nodes) of the original graph (or tree). There are three common ways of doing this:
if (A) then {
B
} else {
C
}
DA recursive version of the algorithm:
def dfs(v):
mark v as visited
preorder-process(v)
for all vertices i adjacent to v such that i not visited
dfs(i)
postorder-process(v)Another version, without the recursion:
dfs(graph G)
{
list L = empty
tree T = empty
choose a starting vertex x
search(x)
while(L is not empty)
{
remove edge (v, w) from beginning of L
if w not yet visited
{
add (v, w) to T
search(w)} }
}
search(vertex v)
{
visit v
for each edge (v, w)
add edge (v, w) to the beginning of L
}
Here are some algorithms where DFS is used: