There are two basic ways to traverse a graph to visit every node:
In a depth-first traversal, the algorithm goes down one route as possible before backtracking and taking the next route. Depth-first traversals can be used to navigate a maze.
In a breadth-first traversal, nodes are visited in order of distance from the start node. Breadth-first traversals can be used to find the shortest path for an unweighted graph.
There are three basic tree-traversal algorithms:
In Reverse Polish (postfix) notation, the operator follows the operand. For example, the infix expression 3 - 4 * 2
becomes 3 4 2 * -
. RPN is used because:
In linear search, items in a list are checked one-by-one to see if they are equal to the item being searched for. Linear search has a time complexity of
In binary search, the number of items being searched is repeatedly halved by comparing the middle item of the list with the item being searched for, which requires a sorted list. Binary search has a time complexity of
In binary tree search, the same idea as binary search is used, except at each stage, a left or right subtree is eliminated. Binary tree search also has a time complexity of
In bubble sort, with each pass the largest item is 'bubbled' to the end of the list, by swapping each pair of items if the first one is larger. Each pass has
In merge sort:
Dijkstra's algorithm is used to find the shortest path between a specific start node and every other node in a weighted graph. It is similar to a breadth first traversal, but uses a priority queue.
The pseudocode of Dijkstra's algorithm is as follows (SPEC: "Students will not be expected to recall the steps in Dijkstra's shortest path algorithm."):
procedure Djkstra(G, v) is
let the distance of the start node be zero
let the distance of all other nodes be infinity
let Q be a priority queue with the start node
let the parent of all nodes be -1
while Q is not empty do
v = s.dequeue()
for each unvisited neighbour u of v
newDistance = distanceToV + distanceFromVToU
if newDistance < distanceAtU THEN
distanceAtU = newDistance
parentOfU = v
procedure DFS(G, v) is
label v as visited
for all directed edges from v to w that are in G.adjacentEdges(v) do
if vertex w is not labeled as visited then
recursively call DFS(G, w)
procedure DFS_iterative(G, v) is
let S be a stack
S.push(v)
while S is not empty do
v = S.pop()
if v is not labeled as visited then
label v as visited
for all edges from v to w in G.adjacentEdges(v) do
S.push(w)
procedure BFS(G, root) is
let Q be a queue
label root as visited
Q.enqueue(root)
while Q is not empty do
v = Q.dequeue()
if v is the goal then
return v
for all edges from v to w in G.adjacentEdges(v) do
if w is not labeled as visited then
label w as visited
w.parent := v
Q.enqueue(w)
Footnote on depth-first traversals
It may be easier to understand by just reading the pseudocode. Both recursive and non-recursive examples are below (from Wikipedia).↩︎
Footnote on breadth-first traversals
It may be easier to understand by just reading the pseudocode (from Wikipedia).↩︎
Footnote on time complexity of bubble sort
Any reasonable implementation of bubble sort (though is there such thing?) would have