Professional Documents
Culture Documents
Decrease-and-Conquer Technique
The decrease-and-Conquer technique is based on exploiting the
relationship between a solution to a given instance of a problem and a
solution to a smaller instance of the same problem.
Once such a relationship is established, it can be exploited either
top down (recursively) or bottom up (without a recursion).
Decrease-by-a-constant
In the decrease-by-a-constant variation, the size of an instance is
reduced by the same constant (typically, this constant is equal to one) on
each iteration of the algorithm.
Decrease-by-a-Constant Factor
In the decrease-by-a-constant factor variation, the size of a problem
instance is reduced by the same constant factor on each iteration of the
algorithm. In most applications, this constant factor is equal to two.
Note:
Consider the problem of exponentiation: Compute an
Brute Force: an = a * a * a * a * . . . * a
Divide and conquer: an = an/2 * an/2
Decrease by one: an = an-1 * a
Decrease by constant factor: an = (an/2)2 if n is even
an = (a(n-1)/2)2 . a if n is odd
Though the arguments on the right-hand side are always smaller than
those on the left-hand side, they are smaller neither by a constant nor by
a constant factor.
Insertion Sort
Decrease – by – one technique is applied to sort an array A[0 . . . n-1].
We assume that the smaller problem of sorting the array A[0 . . . n-2] has
already been solved to give us a sorted array of size n – 1:
A[0] ≤ . . . ≤ A[n – 2].
How can we take the advantage of this solution to the smaller problem to
get a solution to the original problem by taking into account the element
A[n-1]?
All we need is to find an appropriate position for A[n – 1] among
sorted elements and insert it there.
As shown in below figure, starting with A[1] and ending with A[n – 1],
A[i] is inserted in its appropriate place among the first i elements of the
array that have been already sorted (but, unlike selection sort, are
generally not in their final positions).
Best-case Efficiency
In the Best case, the comparison A[j] > v is executed only once on every
iteration of outer loop.
It happens if and only if A[i – 1] ≤ A[i] for every i = 1, . . . n – 1, i.e.,
if the input array is already sorted in ascending order.
n-1
Cbest(n) = ∑1 = n - 1 Є Θ(n)
i=1
Graph Traversal
Graph traversal refers to the process of visiting each vertex in a graph.
There are two principal Graph traversal algorithms:
Depth-First Search
DFS starts visiting vertices of a graph at an arbitrary vertex by marking it
as having been visited.
On each iteration, the algorithm proceeds to an unvisited vertex that is
adjacent to the last visited vertex.
This process continues until a dead end – a vertex with no adjacent
unvisited vertices – is encountered.
At a dead end, the algorithm backs up one edge to the vertex it came
from and tries to continue visiting unvisited vertices from there.
The algorithm eventually halts after backing up to the starting vertex,
with the latter being a dead end.
By this time, all the vertices in the same connected component have been
visited.
If unvisited vertices still remain, the depth-first search must be restarted
at any one of them.
It is convenient to use a stack to trace the operation of DFS.
We push a vertex onto the stack when the vertex is reached for first
time, and we pop a vertex off the stack when it becomes a dead end.
The DFS forest in the previous figure exhibits all four types of edges
possible in a DFS forest of a directed graph: tree edges (ab, bc, de),
back edges (ba) from vertices to their ancestors, forward edges (ac)
from vertices to their descendants in the tree other than their children,
and cross edges (dc), which are none of the above mentioned types.
Pseudocode of DFS
Applications of DFS
Checking connectivity: Since DFS halts after visiting all the vertices
connected by a path to the starting vertex, checking a graph’s
connectivity can be done as follows - Start a DFS traversal at an
arbitrary vertex and check, after the algorithm halts, whether all the
graph’s vertices will have been visited. If they have, the graph is
connected; otherwise, it is not connected.
Checking acyclicity: If the DFS forest does not have back edges, then it
is clearly acyclic.
Instead of a stack, BFS uses a queue. The queue is initialized with the
traversal’s starting vertex, which is marked as visited.
On each iteration, the algorithm identifies all unvisited vertices
that are adjacent to the front vertex, marks them as visited, and
adds them to the queue; after that, the front vertex is removed
from the queue.
BFS traversal is similar to level-by-level tree traversal.
Pseudocode of BFS
Applications of BFS
DFS BFS
Data structure stack queue
No. of vertex orderings 2 orderings 1 ordering
Edge types (undirected graphs) tree and back edges tree and cross edges
Applications connectivity, connectivity,
acyclicity, acyclicity,
articulation points minimum-edge paths
Efficiency for adjacency matrix Θ(|V|2) Θ(|V|2)
Efficiency for adjacency lists Θ(|V| + |E|) Θ(|V| + |E|)
Topological Sorting
Example:
Consider a set of five required courses {C1, C2, C3, C4, C5} a part-time
student has to take in some degree program.
The courses can be taken in any order as long as the following course
prerequisites are met: C1 and C2 have no prerequisites, C3 requires C1
and C2, C4 requires C3, and C5 requires C3 and C4. The student can
take only one course per term.
1. DFS-based algorithm:
DFS traversal noting the order vertices are popped off stack (i.e., the
order in which vertices become dead ends).
Reverse order solves topological sorting
Back edges encountered?→ NOT a dag!
Figure: (a) Digraph for which the topological sorting problem needs to be solved.
(b) DFS traversal stack with the subscript numbers indicating the popping-off
order.
(c) Solution to the problem.
Example: Solve the topological sorting problem for the following digraph using:
a) DFS-based algorithm
b) Source removal algorithm
1 2 1 2 1 2 1
4 3 3
Generating Permutations
Problems:
start 1
insert 2 into 1 right to left 12 21
insert 3 into 12 right to left 123 132 312
insert 3 into 21 left to right 321 231 213
insert 4 into 123 right to left 1234 1243 1423 4123
insert 4 into 132 left to right 4132 1432 1342 1324
insert 4 into 312 right to left 3124 3142 3412 4312
insert 4 into 321 left to right 4321 3421 3241 3214
insert 4 into 231 right to left 2314 2341 2431 4231
insert 4 into 213 left to right 4213 2413 2143 2134
Soln: 1 2 3
1 3 2
3 1 2
3 2 1
2 3 1
2 1 3
The natural place for permutation n n-1 . . .1 seems to be the last one on
the list. This would be the case if permutations were listed in increasing
order – also called the lexicographic order.
Example:
Soln:
123
132
213
231
312
321
Presorting :
Many problems involving lists are easier when list is sorted.
searching
checking if all elements are distinct (element uniqueness)
Worst-case Efficiency:
T(n) = Tsort(n) + Tscan(n) Є Θ(nlog n) + Θ(n) = Θ(nlog n)
The running time of this algorithm is the sum of the time spent on
sorting and the time spent on checking consecutive elements. It is the
sorting part that will determine the overall efficiency of the algorithm.
We can sort the array first and then check only its consecutive elements:
if the array has equal elements, a pair of them must be next to each
other and vice versa.
The brute-force approach for computing a mode would scan the list and
compute the frequencies of all its distinct values, then find the value with
the largest frequency.
AVL TREES
AVL trees were invented in 1962 by two Russian scientists, G. M.
Adelson-Velsky and E. M. Landis, after whom this data structure is
named.
Note:
The balance factor of a node is 0 if and only if the height of the left
subtree and height of right subtree are same.
The balance factor of a node is 1 if the height of the left subtree is one
more than height of right subtree (left heavy).
The balance factor of a node is -1 if the height of the right subtree is one
more than height of left subtree (right heavy).
The height of empty tree is -1.
If there are several nodes with the ±2 balance, the rotation is done for the
tree rooted at the unbalanced node that is the closest to the newly
inserted leaf.
Heaps
DEFINITION: A heap can be defined as a binary tree with keys assigned to its
nodes (one key per node) provided the following two conditions are met:
1. The tree’s shape requirement - the binary tree is almost complete or
complete. i.e., all its levels are full except possibly the last level, where
only some rightmost leaves may be missing.
2. The parental dominance requirement
the key at each node is greater than or equal to the keys at its
children. We call this variation a max-heap.
or
The key at each node is smaller than or equal to the keys at its
children. We call this variation a min-heap.
1. There exists exactly one almost complete binary tree with n nodes. Its
height is equal to log2 n .
2. The root of a heap always contains its largest element.
3. A node of a heap considered with all its descendants is also a heap.
4. A heap can be implemented as an array by recording its elements in the
top-down, left-to-right fashion. It is convenient to store the heap’s
elements in positions 1 through n of such an array, leaving H[0] unused.
In such a representation,
a. the parental node keys will be in the first n/2 positions of the
array, while the leaf keys will occupy the last n/2 positions;
b. the children of a key in the array’s parental position i(1 ≤ i ≤ n/2 )
will be in positions 2i and 2i + 1, and correspondingly, the parent
of a key in position i ( 2 ≤ i ≤ n) will be in position i/2 .
Construction of a Heap
Each key on level i of the tree will traverse to the leaf level h in the worst
case of the heap construction algorithm.
Since moving to next level down requires two comparisons – one to find
the larger child and the other to determine whether the exchange is
Therefore, the total number of key comparisons in the worst case will be
2 2 9 9 9 9
9 2 2 7 2 7 6 7
6 2
9 9
9
6 7 6 7
6 8
2 5 2 5 8 2 5 7
Heapsort
So, for the number of key comparisons, C(n), needed for eliminating the
root keys from heaps of diminishing sizes from n to 2 is given by the
inequality:
Therefore,
the time complexity for the second stage = 2n log2 n ≈ n log2 n.