cp2530 - appspot.combranko-cirovic.appspot.com/cp2530/cp2530.notes.pdf · analysis of algorithms...

271
CP2530 Algorithms and Data Structures

Upload: lephuc

Post on 30-Jan-2018

215 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

CP2530Algorithms and Data Structures

Page 2: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

ANALYSIS OF ALGORITHMS

Analysis is more reliable than experimentation. Testing will reveal behaviour for some inputs, while analysis tells us about algorithm’s behaviour for a! inputs.

There are many different solutions to the same problem. Analysis can help us choose among different solutions.

Performance of a program can be predicted before actual implementation. Analysis gives us better understanding where the “slow” and “fast” parts are.

Page 3: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

MOTIVATION

Recall Fibonacci sequence. It can be recursively defined as:

!"#

f ( x ) = 1

f ( x - 1) + f ( x - 2)if x = 1 or x = 2otherwise

Here we have two base cases, when argument x is either 1 or 2, i.e. f( 1 ) = 1 and f( 2 ) = 1, reflecting the fact that first two integers in the sequence are 1, 1.

Page 4: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

FIBONACCI

The original formula gives rise to natural recursive implementation :

0 int f(int n) {1 if(n == 1 || n == 2)2 return 1;3 else4 return f(n - 1) + f(n - 2);5 }

Page 5: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

EFFICIENCY

Basic Question : How much time would recursive algorithm take to compute the nth member of the sequence?

But how to measure time? In seconds? But then the answer changes every time Intel comes out with a faster processor.

To get a rough approximation, we measure time in terms of lines of ( pseudo ) code.

Page 6: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

EFFICIENCY

Line 1 is always executed in the code on slide 4. Depending on the evaluation of line 1 either line 2 or line 4 is executed.

Therefore, the time required to compute the nth Fibonacci number in terms of lines of code is :

time(n) = 2 + time(n - 1) + time(n - 2)

The equation above is called recurrence relation, and we’ll see how to solve them shortly.

Page 7: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

EFFICIENCY

Recursive implementation of Fibonacci numbers is natural, but very inefficient. Here is why, ( intuitively ) :

f(5)

f(4) f(3)

f(2) f(1)f(2)f(3)

f(2) f(1) The same numbers are recomputed ! Try running with n = 45 and wait ...

Page 8: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

FIBONACCI:SECOND APROACH

Recursive algorithm is slow because it recomputes the same numbers over and over again.

Our second algorithm stores computed numbers in the array :

0 int f(int n) {1 int[] a = new int[n];2 a[0] = a[1] = 1;3 for(int i = 2; i < n; i++)4 a[i] = a[i - 1] + a[i - 2];5 return a[n - 1];6 }

Page 9: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

Lines 1, 2 and 5 are executed unconditionally ( 3 times ). Line 3 is executed n - 1 times and line 4 is executed n - 2 times. So

time(n) = 3 + n - 1 + n - 2 = 2n

For n = 45, it takes 90 steps, roughly 25 million times faster than recursive implementation!

FIBONACCI:SECOND APROACH

Page 10: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

SPACE COMPLEXITY

Efficiency ( running time ) is not our only concern or the only thing that we can analyze mathematically.

If a program takes a lot of time ( reasonably ), we can still run it and just wait longer for a result.

However, if a program takes a lot of memory ( space ), we may not be able to run it at all.

Recursive algorithm takes a constant amount of space : some for local variables as well as return addresses.

Page 11: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

SPACE ANALYSIS

f(n)

f(3)

f(2) f(1)

f(n-1) f(n-2)

f(n-3)f(n-2) f(n-4)f(n-3)

The length of any such path is at most n, so the space complexity is again some constant factor times n.

Page 12: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

Iterative algorithm uses roughly the same amount of space - size of the array ( n ). Since each step through the loop uses only two previous values, we can improve space complexity :

SPACE ANALYSIS

0 int f(int n) {1 int p = 1;2 int t = 0;3 for(int i = 1; i < n; i++) {4 int c = p + t;5 p = t;6 t = c;7 }8 return c;9 }

Page 13: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

SPACE ANALYSIS

Lines 1, 2 and 8 are executed unconditionally ( 3 times ). Line 3 is executed n + 1 times, lines 4, 5 and 6 are executed n times. So

time(n) = 3 + n + 3n = 4n + 3

Because of swapping, this algorithm is slightly slower than array based algorithm, but it uses much less space.

Page 14: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

GROWTH OF FUNCTIONS

Quite often we cannot predict the running times of algorithms exactly. Consider the following one, computing the maximum value in the array :

0 int max(int[] a) {1 int m = a[0];2 for(int i = 1; i < a.length; i++) {3 if(a[i] > m)4 m = a[i];5 }6 return m;7 }

Page 15: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

GROWTH OF FUNCTIONS

Lines 1 and 6 are executed unconditionally ( 2 times ). Line 2 is executed n ( a.length ) times, line 3 is executed n - 1 times. But we can’t tell how many times line 4 will be executed. So

time(n) = 2 + n + n - 1 + A = 2n + 1 + A

In the expression above we know everything except the quantity A, which is the number of times we must change the value for the current maximum.

Page 16: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

GROWTH OF FUNCTIONS

Minimum value of A ( best case )In function max, the best case is when array is sorted in descending order, i.e. step 4 is never executed and the running time is 2n + 1.

Maximum value of A ( worst case )In function max, the worst case is when array is sorted in ascending order, i.e. step 4 is executed n - 1 times and the running time is 3n.

The analysis usually consist of finding the :

Page 17: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

GROWTH OF FUNCTIONS

It is the rate of growth that really interests us : how the running time of an algorithm increases with the size of an input in the limit.

Since we are interested in asymptotic efficiency of algorithms ( when input size is large ), when we define running times we simply ignore constants and lower degree variables.

For example, if T(n) = an2 + bn + c, where a, b and c are nonnegative constants, we’ll write Θ(n2) or O(n2).

Page 18: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

Θ-NOTATION

What follows is fancy mathematical lingo to express the fact that if my code takes 3n4 + 2n² - 5 steps, I don’t care about lower terms and constants - it takes n4 steps. That’s it!

For a given function g(n) we denote by Θ(g(n)) the set of functions :

Θ(g(n)) = { f(n) : ∃c₁, c₂, n₀ > 0 such that 0 ≤ c₁g(n) ≤ f(n) ≤ c₂g(n) ∀n ≥ n₀ }

Any function f(n) in Θ(g(n)) is bounded by c₁g(n) and c₂g(n) for all n ≥ n₀. So we write f(n) ∈ Θ(g(n)) or f(n) = Θ(g(n)).

Page 19: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

Θ-NOTATION

c₁g(n₁)

f(n₁)

c₂g(n₁)

n₁n₀

c₂g(n)

f(n)

c₁g(n)

runningtime

n - size of input

Graphically, Θ-notation can be represented as :

Page 20: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

O-NOTATIONFor a given function g(n) we denote by O(g(n)) the set of functions :

O(g(n)) = { f(n) : ∃c, n₀ > 0 such that 0 ≤ f(n) ≤ cg(n) ∀n ≥ n₀ }

Θ-notation asymptotically bounds a function from above and below. O-notation stands for asymptotic upper bound ( worst case running time ).

Again we write, for example, 2n² + 3n - 2 = O(n²), but the real meaning is 2n² + 3n - 2 ∈ O(n²).

Page 21: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

O-NOTATIONGraphically, O-notation can be represented as :

f(n₁)

cg(n₁)

n₁n₀

cg(n)

f(n)

runningtime

n - size of input

Page 22: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

The most common values in the analysis of algorithms are :

O-NOTATION

constant logarithmic linear

O(1) O(log n) O(n)

quadratic polynomial exponential

O(n²) O(nk) ( k ≥ 1 ) O(an) ( a > 1 )

O-notation should be used to characterize function as closely as possible. While it is true that f(n) = 4n3 + 3n4/3 is in O(n5), it is more accurate to say that it is in O(n3).

Page 23: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

Ω-NOTATION

For a given function g(n) we denote by Ω(g(n)) the set of functions :

Ω(g(n)) = { f(n) : ∃c, n₀ > 0 such that 0 ≤ cg(n) ≤ f(n) ∀n ≥ n₀ }

Ω-notation stands for asymptotic lower bound ( best case running time ).

Page 24: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

Ω-NOTATIONGraphically, Ω-notation can be represented as :

cg(n₁)

f(n₁)

n₁n₀

f(n)

cg(n)

runningtime

n - size of input

Page 25: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

RECURRENCES

When an algorithm contains a recursive call, its running time can often be described by recurrence, which is an equation that describes function in terms of smaller inputs.

For example, recurrence that describes recursive Fibonacci function is :

!"#

T(n) = 1T(n - 1) + T(n - 2)

if n = 1 or n = 2otherwise

The importance of solving recurrences is in obtaining asymptotic Θ or O bounds.

Page 26: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

HOMOGENEOUS RECURRENCES

Recurrences of the form : a0T(n) + a1T(n - 1) + ... + akT(n - k) = 0

are called homogeneous recurrences.

For example, Fibonacci sequence, in terms of recurrences,T(n) - T(n - 1) - T(n - 2) = 0 is homogeneous recurrence.

With each recurrence we associate characteristic polynomial : p(x) = a0xk + a1xk-1 + ... + ak

For example, x2 - x - 1 is p(x) for Fibonacci sequence.

Page 27: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

Let ri denote the ith root of the characteristic polynomial. Then homogeneous recurrence has solution of the form :

∑cirin = c1r1n + c2r2n + ... + ckrkn

provided that all roots are distinct.

Coefficients c1, c2, ..., ck can be determined from k initial conditions ( trivial recursive cases ) by solving the system of k linear equations in k unknowns.

HOMOGENEOUS RECURRENCES

Page 28: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

EXAMPLE

Fibonacci recurrence is defined as T(n) - T(n - 1) - T(n - 2) = 0 with its characteristic polynomial x2 - x - 1. The roots of this polynomial are :

1 + √52r1 = r2 = 1 - √5

2

So the solution is of the form :

1 + √52c1 c2

1 - √52+

n n

T(n) = '(

'(

'(

'(

Page 29: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

EXAMPLE

We find coefficients c1 and c2 from initial conditions T(1) = 1 and T(2) = 1. Their values are c1 = 1 / √5 and c1 = -1 / √5. Thus

Since (1 + √5) / 2 > 1 and (1 - √5) / 2 < 1, we have

T(n) = O(1.618n)

That’s bad. Very bad! It will take ~2,500,000,000 steps to compute the 45th member of the Fibonacci sequence!

1 + √52

1 - √52

-n n

T(n) = √51___ )

*)*

'(

'(

'(

'(

Page 30: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

THE MASTER METHOD

The master method is a method for solving recurrences of the form :

where a ≥ 1, b > 1 and f(n) is asymptotically positive function. Then T(n) can be bounded asymptotically as follows :

nb_T(n) = aT + f(n)'

('(

Page 31: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

1. If f(n) = O(nlogba - ε) for some constant ε > 0, thenT(n) = Θ(nlogba).

2. If f(n) = Θ(nlogba), then T(n) = Θ(nlogba log n).

3. If f(n) = Ω (nlogba + ε) for some constant ε > 0 and if af(n/b) ≤ cf(n) for some constant c < 1, then T(n) = Θ(f(n)).

THE MASTER METHOD

nb_T(n) = aT + f(n)'

('(

Page 32: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

EXAMPLES (1)

Consider T(n) = 9T(n / 3) + n.

For this recurrence we have a = 9, b = 3, f(n) = n.

Thus nlog39 = n2. Let ε = 6.

Since f(n) = n = O(nlog39 - 6) = O(nlog33) = O(n), we apply case (1) and conclude T(n) = Θ(nlog39) = Θ(n2).

Page 33: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

EXAMPLES (2)

Consider T(n) = T(2n / 3) + 1.

For this recurrence we have a = 1, b = 3/2, f(n) = 1

Thus nlog3/21 = n0 = 1.

Since f(n) = 1 = Θ(nlog3/21) = Θ(1), we apply case (2) and conclude T(n) = Θ(nlog3/21 log n) = Θ(log n).

Page 34: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

EXAMPLES (3)

Consider T(n) = 3T(n / 4) + n log n.

For this recurrence we have a = 3, b = 4, f(n) = n log n and thus nlog43.

Since log43 < 1, choose ε such that ε + log43 = 1.

Then nlog43+ε = n1 = n and obviously f(n) = n log n = Ω(n)( case 3 is candidate ).

Page 35: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

EXAMPLES (3)

Next we have to show that regularity condition applies :

a f(n / b) ≤ cf(n) for some constant c

3 (n / 4) log (n / 4) ≤ cn log n

Let c = 3 / 4. The we have :

(3n / 4) log (n / 4) < (3n / 4) log n

Case 3 applies and we conclude T(n) = Θ(n log n).

Page 36: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

DATA STRUCTURES

So far, we studied static, fixed-size data structures such as arrays.

Quite often, it is not possible to predict, in advance, how much memory is needed to carry out computation ( can compiler predict how many variables you will declare? )

For this reason, we’ll study dynamic data structures - structures that can grow, as well as shrink, at run time.

Page 37: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

SELF-REFERENTIAL CLASSES

All dynamic data structures are based on the concept ofself-referential nodes.

Self-referential nodes are implemented through self-referential classes which contain data field(s) as well as references ( links ) to objects of the same type.

Pictorially, self-referential node can be represented as :

data

Page 38: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

Node.javaclass Node { private int data; private Node link;

public Node() { data = 0; link = null; }

public void setData(int data) { this.data = data; }

Page 39: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

Node.java public int getData() { return data; }

public void setLink(Node link) { this.link = link; }

public Node getLink() { return link; }}

Page 40: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

DYNAMIC MEMORY ALLOCATION

Creating and maintaining data structures requires dynamic memory allocation - ability to request and allocate more memory at run time.

Recall that in Java, the new operator is essential in dynamic memory allocation. For example : Node n = new Node();would request enough memory to store object of type Node and assign reference to variable n.

Unlike in C/C++, we don’t have to worry about deleting nodes we don’t need. Java garbage collector does the job!

Page 41: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

TestNode.java

class TestNode { public static void main(String[] args) { Node n1, n2, n3, temp; n1 = new Node(); n2 = new Node(); n3 = new Node(); n1.setData(1); n1.setLink(n2); n2.setData(2); n2.setLink(n3); n3.setData(3);

Page 42: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

TestNode.java

temp = n1; while(temp != null) { System.out.print(temp.getData() + " "); temp = temp.getLink(); } System.out.println(); }}

Page 43: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

LINKED NODES

This is what we have created here, pictorially :

1

n1

2

n2

temp 3

n3

null

The major disadvantage with this approach is that we have to declare nodes in advance. Instead of doing so we’ll develop methods to create and link nodes dynamically.

Page 44: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

STACKS

The simplest dynamic data structure is stack - new nodes can be added to and removed from the top only.

For this reason, stack is referred to as LIFO ( Last-In-First-Out ) data structure.

In order to implement stack, we need two private variables :Node top and int size, initially set to null and 0, respectively.

Primary methods are void push(int data) which adds a new node on top of the stack, and void pop() which removes node from the top.

Page 45: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

STACKS : push

This is the sequence of steps taken every time the push(data) method is called :

1. Dynamically create new node : Node n = new Node();

0

n

null

null

topsize = 0

Page 46: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

STACKS : push

2. Set data ( assume 1 ) : n.setData(data);

1

n

null

null

topsize = 0

3. Link newly created node to the previous one : n.setLink(top);

Page 47: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

STACKS : push

4. Set top reference to newly created node : top = n;

size = 0

5. Increment size : size++;

1

n

null

top

Page 48: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

STACKS : push

size = 11

null

top

0

n

null

2

size = 2

Page 49: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

STACKS : push

public void push(int data) { Node n = new Node(); n.setData(data); n.setLink(top); top = n; size++;}

Page 50: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

Pop method removes the node on top. This is the sequence of steps taken every time the pop() method is called :

STACKS : pop

1. If the stack is empty ( size is zero or top is null ), report it and exit. Otherwise, set top to the node below : top = top.getLink();

2. Decrement size : size--;

Page 51: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

STACKS : pop

size = 11

null

top

2

size = 2

Page 52: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

STACKS : pop

public void pop() {if(isEmpty())System.out.println("Stack is empty.");

else {top = top.getLink();size--;

}}

Page 53: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

Stack.java

class Stack { Node top; int size; public Stack() { top = null; size = 0; }

Page 54: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

Stack.java

public void push(int data) { Node n = new Node(); n.setData(data); n.setLink(top); top = n; size++;}

Page 55: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

Stack.java

public boolean isEmpty() { if(size == 0) return true; else return false;}

Page 56: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

Stack.java

public void pop() { if(isEmpty()) System.out.println("Stack is empty."); else { top = top.getLink(); size--; }}

Page 57: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

Stack.java

public void print() {if(isEmpty())System.out.print("Stack is empty");

else {Node temp = top;while(temp != null) {System.out.print(temp.getData() + " ");temp = temp.getLink();

}}System.out.println();

}

Page 58: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

TestStack.java

class TestStack { public static void main(String[] args) { Stack s = new Stack(); s.push(1); s.push(2); s.push(3); s.print(); s.pop(); s.print(); s.pop(); s.pop(); s.print(); s.pop(); }}

Page 59: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

LINKED LISTS

Linked lists are data structures similar to stacks. Insertions are done at the end of the list called tail.

Here we use another reference - head, which points to the first node in the list.

With two references, it is possible to search, sort, remove entries not only at tail etc.

Hence, in order to implement linked lists, we need two references Node head, tail and int size. References are initialized to null and size to 0;

Page 60: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

LINKED LISTS : insert

This is the sequence of steps taken every time the insert(data) method is called :

1. Dynamically create new node : Node n = new Node();

0

n

null

null

headsize = 0

null

tail

Page 61: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

LINKED LISTS : insert

2. Set data ( assume 1 ) : n.setData(data);

1

n

null

null

headsize = 0

null

tail

Page 62: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

LINKED LISTS : insert

3. If list is empty set head reference to newly created node n ( head = n ). Otherwise, link this node to the last one : tail.setLink(n);

1

n

null

headsize = 0

null

tail

Page 63: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

LINKED LISTS : insert

4. Set tail reference to newly created node : tail = n;

5. Increment size : size++;

1

n

null

headsize = 0

tail

Page 64: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

LINKED LISTS : insert

1

null

headsize = 1

tail

0

n

null

2

size = 2

Page 65: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

LINKED LISTS : insert

public void insert(int data) { Node n = new Node(); n.setData(data); if(isEmpty()) head = n; else tail.setLink(n); tail = n; size++;}

Page 66: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

LINKED LISTS : removeRemove method removes the node at tail. This is the sequence of steps taken every time the remove() method is called :

1. If the list is empty ( size is zero or head/tail are null ), report it and exit.

2. If size is 1, reset head and tail to null and size to zero.

3. Otherwise, traverse the list until we find the node just before tail :

while(temp.getLink() != tail) temp = temp.getLink();

Page 67: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

LINKED LISTS : remove

1

head tail

2

null

size = 2temp

4. Set tail to temp : tail = temp;

5. Set tail’s link to null : tail.setLink(null);

6. Decrement size : size--;

Page 68: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

LINKED LISTS : remove

1

head tail

2

null

size = 2temp

null

size = 1

Page 69: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

LINKED LISTS : remove

public void remove() { if(isEmpty()) System.out.println("List is empty."); else if(size == 1) { head = tail = null; size = 0; }

Page 70: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

LINKED LISTS : remove

else { Node temp = head; while(temp.getLink() != tail) temp = temp.getLink(); tail = temp; tail.setLink(null); size--; }}

Page 71: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

LinkedList.java

class LinkedList { private Node head; private Node tail; int size; public LinkedList() { head = tail = null; size = 0; }

Page 72: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

LinkedList.java

public boolean isEmpty() { if(size == 0) return true; else return false; }

Page 73: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

LinkedList.java

public void insert(int data) { Node n = new Node(); n.setData(data); if(isEmpty()) head = n; else tail.setLink(n); tail = n; size++; }

Page 74: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

LinkedList.java

public void remove() { if(isEmpty()) System.out.println("Can't remove. List is empty."); else if(size == 1) { head = tail = null; size = 0; } else { Node temp = head; while(temp.getLink() != tail) temp = temp.getLink(); tail = temp; tail.setLink(null); size--; } }

Page 75: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

LinkedList.java

public void print() { if(isEmpty()) System.out.println("List is empty."); else { Node temp = head; while(temp != null) { System.out.print(temp.getData() + " "); temp = temp.getLink(); } System.out.println(); } }}

Page 76: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

TestLinkedList.java

class TestLinkedList { public static void main(String[] args) { LinkedList l = new LinkedList(); l.insert(1); l.insert(2); l.insert(3); l.print(); l.remove(); l.print(); l.remove(); l.print(); l.remove(); l.print(); l.remove(); l.print(); }}

Page 77: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

QUEUES

Queue is dynamic data structure similar to linked list : it can be described by two references head and tail, and size. Fundamental methods are :

void enqueue(int data) : identical to insert(int data) in linked list. New node is linked at the tail of queue.

void dequeue() : removes node from head. For this reason queues are called FIFO ( First-In-First-Out ) data structures.

Page 78: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

QUEUES : dequeue

head tail

2

null

1

size = 2size = 1

Page 79: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

Queue.java

class Queue { private Node head; private Node tail; private int size; public Queue() { head = tail = null; size = 0; }

Page 80: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

Queue.java

public boolean isEmpty() { if(size == 0) return true; else return false; }

Page 81: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

Queue.java

public void enqueue(int data) { Node n = new Node(); n.setData(data); if(isEmpty()) head = n; else tail.setLink(n); tail = n; size++; }

Page 82: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

Queue.java

public void dequeue() { if(isEmpty()) System.out.println("Queue is empty"); else if(size == 1) { head = tail = null; size = 0; } else { head = head.getLink(); size--; } }

Page 83: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

Queue.java

public void print() { if(isEmpty()) System.out.println("Queue is empty."); else { Node temp = head; while(temp != null) { System.out.print(temp.getData() + " "); temp = temp.getLink(); } System.out.println(); } }}

Page 84: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

TestQueue.java

class TestQueue { public static void main(String[] args) { Queue q = new Queue(); q.enqueue(1); q.enqueue(2); q.print(); q.dequeue(); q.print(); q.dequeue(); q.print(); q.dequeue(); q.print(); }}

Page 85: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

BINARY TREES

Graph G = ( V, E ) is the set of vertices and edges.

Cycle C is a path in graph, i.e. distinct sequence of vertices and edges, that begins and ends with the same vertex.

Page 86: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

BINARY TREES

Tree T is acyclic graph. It is rooted in a root vertex.

Binary Tree is a tree in which any node can have at most two leaves ( children ).

rootroot

Page 87: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

BINARY SEARCH TREE

All keys ( if any ) in left subtree with respect to root vertex precede the key in the root.

The key in the root vertex precedes all keys ( if any ) in its right subtree.

The left and right subtrees of the root are again binary search trees.

Binary Search Tree is a binary tree which is either empty or in which each vertex contains a key that satisfies conditions :

Page 88: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

BINARY SEARCH TREE

2

1 3

root

Binary Search Tree

null

2

1 3

null null null

root

Binary Search Tree as data structure

Page 89: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

BNode.java

class BNode { private int data; private BNode leftLink; private BNode rightLink; public BNode() { data = 0; leftLink = rightLink = null; }

Page 90: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

BNode.java

public void setData(int data) { this.data = data; } public int getData() { return data; }

Page 91: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

BNode.java

public void setLeftLink(BNode leftLink) { this.leftLink = leftLink; } public BNode getLeftLink() { return leftLink; }

Page 92: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

BNode.java

public void setRightLink(BNode rightLink) { this.rightLink = rightLink; } public BNode getRightLink() { return rightLink; }}

Page 93: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

BINARY TREE: INSERTION

1

3

2

1 - 2 - 3

1

3

2

1 - 3 - 2

3

1

2

3 - 2 - 1

3

1

2

3 - 1 - 2

Nodes cannot be inserted into a binary tree in a predefined way. Every insertion must preserve the binary tree. Different insertions might result in a different tree.

Page 94: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

BINARY TREE: INSERTION

2

1 3

Observe that both sequences, 2 - 1 - 3 and 2 - 3 - 1 will yield the same tree.

Hence, before we can insert node into a binary tree, we have to find the proper position for that node. Initially, binary tree consists of a single reference root which is null.

Page 95: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

BINARY TREE: INSERTION

2

4

3

1

5

root

temptempb.insert(2);b.insert(1);b.insert(4);b.insert(3);b.insert(5);

Page 96: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

BINARY TREE: INSERTION

public void insert(int data) { BNode b = new BNode(); b.setData(data); if(root == null) root = b; else { BNode temp = root; while(temp != null) {

Page 97: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

BINARY TREE: INSERTION

if(data < temp.getData()) { if(temp.getLeftLink() != null) temp = temp.getLeftLink(); else { temp.setLeftLink(b); break; }}

Page 98: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

BINARY TREE: INSERTION

else if(data > temp.getData()) { if(temp.getRightLink() != null) temp = temp.getRightLink(); else { temp.setRightLink(b); break; }}

Page 99: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

BINARY TREE: INSERTION

else { System.out.println("Error. Duplicate."); break; } }}

Page 100: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

TREE TRAVERSAL

In many applications it is necessary to visit nodes in a regular way. Typically we have to visit the node ( V ), traverse its left subtree ( L ) and finally traverse its right subtree ( R ) :

V L R V R L L V R R V L L R V R L V

By standard convention, these six traversals are reduced to three, by traversing the left subtree before the right.

Their names are : Preorder ( VLR ), Inorder ( LVR ) and Postorder ( LRV ).

Page 101: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

PREORDER (VLR)

2

4

3

1

5

root

temp

412 3 5

Page 102: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

INORDER (LVR)

2

4

3

1

5

root

321 4 5

temp

Page 103: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

POSTORDER (LRV)

2

4

3

1

5

root

531 4 2

temp

Page 104: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

BTree.javaclass BTree { private BNode root; public BTree() { root = null; } public void insert(int data) { BNode b = new BNode(); b.setData(data); if(root == null) root = b;

Page 105: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

BTree.java

else { BNode temp = root; while(temp != null) { if(data < temp.getData()) { if(temp.getLeftLink() != null) temp = temp.getLeftLink(); else { temp.setLeftLink(b); break; } }

Page 106: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

BTree.java

else if(data > temp.getData()) { if(temp.getRightLink() != null) temp = temp.getRightLink(); else { temp.setRightLink(b); break; } }

Page 107: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

BTree.java

else { System.out.println("Error. Duplicate."); break; } } } }

Page 108: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

BTree.java

public void showPreorder() { System.out.print("Preorder traversal: "); preorder(root); System.out.println(); } public void preorder(BNode b) { if(b != null) { System.out.print(b.getData() + " "); preorder(b.getLeftLink()); preorder(b.getRightLink()); } }

Page 109: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

BTree.java

public void showInorder() { System.out.print("Inorder traversal: "); inorder(root); System.out.println(); } public void inorder(BNode b) { if(b != null) { inorder(b.getLeftLink()); System.out.print(b.getData() + " "); inorder(b.getRightLink()); } }

Page 110: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

BTree.java public void showPostorder() { System.out.print("Postorder traversal: "); postorder(root); System.out.println(); } public void postorder(BNode b) { if(b != null) { postorder(b.getLeftLink()); postorder(b.getRightLink()); System.out.print(b.getData() + " "); } }}

Page 111: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

TestBTree.java

class TestBTree { public static void main(String[] args) { BTree b = new BTree(); b.insert(2); b.insert(1); b.insert(4); b.insert(4); b.insert(3); b.insert(5); b.showPreorder(); b.showInorder(); b.showPostorder(); }}

Page 112: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

AVL TREESIf we inserted into a binary tree values 1, 2, 3 the resulting tree would look like :

root 1

2

3

null null

null

null

null

Page 113: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

The worst-case performance ( search ) on binary search tree is when values are inserted in ascending / descending order. It is not better than linear search O(n).

Height-Balance PropertyFor every internal ( non-leaf ) node v of binary search tree T, the heights of the children of v can differ by at most 1.

Any tree that satisfies Height-Balance Property is said to be an AVL tree ( Adelson, Velskii, Landis ). AVL trees maintain the logarithmic height.

AVL TREES

Page 114: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

INSERTION

Nodes are inserted into AVL tree in the same way as they were inserted into Binary Search Tree.

This action might violate height-balance property. If this is the case, tree must be restructured. There are four cases :

1

3

2

1

3

2

3

1

2

3

1

2

Page 115: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

INSERTION

Once the new node x is inserted into a tree ( and linked to its parent! ), we’ll call :

public AVLNode unbalanced(AVLNode x)

Method unbalanced(x) climbs up the tree from x until it either finds unbalanced node by computing hbp or reaches the null reference ( root’s parent ).

If the tree is unbalanced, the method will return reference to unbalanced node ( z ), null otherwise.

Page 116: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

INSERTION

4

53

1 2 6

7

Observe that it is not sufficient to check hbp at root alone. The following tree ( sequence 4 3 5 1 2 6 7 ) is balanced at root, but unbalanced at node 5.

root balanced

unbalanced

Page 117: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

L-ROTATIONroot

b.insert(1);b.insert(2);b.insert(3);

2

1

3

Page 118: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

L-ROTATION

root

1

2

3

null

t2 t3

t1

t0x

y

z

2

1 3

t0 t1 t2 t3

nullroot y

xz

This is L-Rotation in terms of pointers ( mess! ). Most recently inserted node is x, node z is unbalanced :

Page 119: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

Newly inserted node x violates the height-balance property ( H(L) - H(R) = -2 ) in the right subtree with respect to unbalanced node z.

Newly inserted node x is the right child of its parent y.

L-ROTATION

Criteria for L-Rotation :

Page 120: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

void l(x, y, z) AVLNode t0, t1, t2, t3; t0 = z.getLeftLink(); t1 = y.getLeftLink(); t2 = x.getLeftLink(); t3 = x.getRightLink(); y.setLeftLink(z); y.setRightLink(x); y.setParent(z.getParent()); z.setLeftLink(t0); z.setRightLink(t1); z.setParent(y); x.setLeftLink(t2); x.setRightLink(t3); x.setParent(y); if(z == root) root = y;

Page 121: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

root

b.insert(1);b.insert(3);b.insert(2);

LR-ROTATION

1

3

2

Page 122: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

LR-ROTATIONThis is LR-Rotation in terms of pointers ( mess! ). Most recently inserted node is x, node z is unbalanced :

2

1 3

t0 t1 t2 t3

nullroot x

yz

root

1

null

2

t1 t2

t0

x

y

3

z

t3

Page 123: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

Newly inserted node x violates the height-balance property ( H(L) - H(R) = -2 ) in the right subtree with respect to unbalanced node z.

Newly inserted node x is the left child of its parent y.

LR-ROTATION

Criteria for LR-Rotation :

Page 124: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

void lr(x, y, z) AVLNode t0, t1, t2, t3; t0 = z.getLeftLink(); t1 = x.getLeftLink(); t2 = x.getRightLink(); t3 = y.getRightLink(); x.setLeftLink(z); x.setRightLink(y); x.setParent(z.getParent()); z.setLeftLink(t0); z.setRightLink(t1); z.setParent(x); y.setLeftLink(t2); y.setRightLink(t3); y.setParent(x); if(z == root) root = x;

Page 125: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

R-ROTATION

root

b.insert(3);b.insert(2);b.insert(1);

2

3

1

Page 126: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

R-ROTATIONThis is R-Rotation in terms of pointers ( mess! ). Most recently inserted node is x, node z is unbalanced :

2

1 3

t0 t1 t2 t3

nullroot y

zx

2

1

t0 t1

t3

t2

x

y

root

3

nullz

Page 127: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

R-ROTATION

Newly inserted node x violates the height-balance property ( H(L) - H(R) = 2 ) in the left subtree with respect to unbalanced node z.

Newly inserted node x is the left child of its parent y.

Criteria for R-Rotation :

Page 128: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

void r(x, y, z) AVLNode t0, t1, t2, t3; t0 = x.getLeftLink(); t1 = x.getRightLink(); t2 = y.getRightLink(); t3 = z.getRightLink(); y.setLeftLink(x); y.setRightLink(z); y.setParent(z.getParent()); x.setLeftLink(t0); x.setRightLink(t1); x.setParent(y); z.setLeftLink(t2); z.setRightLink(t3); z.setParent(y); if(z == root) root = y;

Page 129: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

RL-ROTATION

root

b.insert(3);b.insert(1);b.insert(2);

3

1

2

Page 130: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

RL-ROTATIONThis is RL-Rotation in terms of pointers ( mess! ). Most recently inserted node is x, node z is unbalanced :

2

1 3

t0 t1 t2 t3

nullroot x

zy

1

2t0

t1

t3

t2

x

y

root

3

nullz

Page 131: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

RL-ROTATION

Newly inserted node x violates the height-balance property ( H(L) - H(R) = 2 ) in the left subtree with respect to unbalanced node z.

Newly inserted node x is the right child of its parent y.

Criteria for RL-Rotation :

Page 132: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

void rl(x, y, z) AVLNode t0, t1, t2, t3; t0 = y.getLeftLink(); t1 = x.getLeftLink(); t2 = x.getRightLink(); t3 = z.getRightLink(); x.setLeftLink(y); x.setRightLink(z); x.setParent(z.getParent()); y.setLeftLink(t0); y.setRightLink(t1); y.setParent(x); z.setLeftLink(t2); z.setRightLink(t3); z.setParent(x); if(z == root) root = x;

Page 133: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

REMOVAL OF NODES IN AVL TREES

CASE 1 : Removal of external nodes ( nodes that do not have children ) ALGORITHM:

1. find node ( x ) with specified key

2. find x’s parent ( y )

3. set y’s left ( right ) link to null

4. possibly handle root

4

62

1 3

root

5

Page 134: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

CASE 1

2

nullroot

x

1

null null

3

null null

y

a.remove(1);

find(1);

y = x.getParent();

if(x == y.getLeft()) y.setLeft(null);else y.setRight(null);

null

Page 135: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

REMOVAL OF NODES IN AVL TREES

CASE 2 : Removal of internal nodes ( nodes that have at least one child ) Subcase ( a ) : 1 child

4

62

1 3

root

5

ALGORITHM:

1. find node ( w ) with specified key

2. if w has single child, set reference x to that child and reference y to w’s parent

3. properly link y to x and possibly handle root, i.e. w is root.

Page 136: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

CASE 2A

4

62

1 3

root

5

4

2

1 3

root

5

w

y

x

Page 137: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

CASE 2BCASE 2 : Removal of internal nodes, subcase ( b ) : 2 children

4

62

1 3

root

5

ALGORITHM:1. find node ( w ) with specified key

2. find node z that follows w in inorder traversal

3. copy value at z to w

4. if z has no children, unlink it; otherwise properly link z’s right subtree to z’s parent.

Page 138: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

CASE 2B

4

62

1 3

root

5

w

z

5 5

62

1 3

root

Page 139: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

REMOVAL OF NODES IN AVL TREES

Deleting a node from AVL tree may result in an unbalanced tree :

5

62

1 3

root 5

2

1 3

root

Page 140: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

REMOVAL OF NODES IN AVL TREES

Resulting tree needs to be balanced using the same rotations as in the case of insertion :

2

1

3

root

5

R-Rotation

3

2

1

5

root

RL-Rotation

Page 141: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

REMOVAL OF NODES IN AVL TREES

Situation is however more complex than in the case of insertion.

More than one rotation might be necessary to balance the tree.

For this reason, it necessary to climb back to the root node checking the balance property at each node.

Play with this at :http://www.qmatica.com/DataStructures/Trees/AVL/AVLTree.html

Page 142: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

find(k) : returns an element with key k

insert(k, e) : inserts element e with key k into a dictionary

remove(k) : removes element with key k from dictionary

HASH TABLES

A dictionary is a collection of pairs ( k, e ) where k is the key and e is an element. Keys uniquely identify each pair. The most common methods are :

The primary purpose of dictionaries is to store elements so that they can be located effectively using keys.

Page 143: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

HASH TABLES

The simplest implementation of dictionaries is an array, where the key is array’s index and element is data stored at that index.

The problem with arrays is that array’s indices are dense and many keys are not. Consider CNA students’ numbers : they are 8 digits long and there are roughly 8,500 students.

The solution to this problem is to use a hash table which consists of two components : bucket array and hash function.

Page 144: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

The hash function is used to map sparse keys to dense locations of the bucket array.

The task of a hash function is to map a key k into an integer in the range [ 0, N - 1 ], where N is the size of a bucket.

One of the simplest hash functions is : h(k) = k mod N

HASH TABLES

Page 145: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

HASH TABLES

Here is an example of a hash table with four buckets storing prime numbers { 2, 5, 11, 23, 37 } :

5 37

2

11

0

1

2

3

2 % 4 = 2

5 % 4 = 1

11 % 4 = 3

23 % 4 = 3

37 % 4 = 1

null

null

null

null23

Page 146: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

If two different keys are mapped into the same bucket, we say that collision occurred.

Obviously, if buckets can store a single element, we would not be able to handle collisions.

Therefore, instead of storing single element in a bucket, we rather store a list of elements. Such a collision resolution is called chaining.

HASH TABLES

Page 147: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

HashTable.java

class HashTable { private LinkedList[] table; private int size; public HashTable(int size) { this.size = size; table = new LinkedList[size]; for(int i = 0; i < size; i++) table[i] = new LinkedList(); }

Page 148: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

HashTable.java

public void insert(int i) { int hashCode = i % size; table[hashCode].insert(i); }

public void remove(int i) { int hashCode = i % size; table[hashCode].remove(i); }

Page 149: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

HashTable.java

public void get(int i) { int hashCode = i % size; int n = table[hashCode].search(i); if(n == -1) System.out.println(i + " is not in the table."); else { System.out.println(i + " is in the bucket " + hashCode + " at position " + n); } }

Page 150: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

HashTable.java

public void print() { for(int i = 0; i < size; i++) { System.out.print("Bucket " + i + ": "); table[i].print(); } }}

Page 151: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

GRAPHS

Graph G = ( V, E ) is the set of vertices and edges.

If e = ( u, v ) is in E, then e is an edge between vertices u and v. Circles represent vertices and arcs ( lines ) represent edges.

Page 152: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

GRAPHS

A

B

C

D

E

F

If pairs of vertices are unordered, graph G is called undirected graph.

If pairs of vertices are ordered, graph G is called directed graph. Represented as line segments / arcs with arrowheads indicating direction.

Page 153: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

GRAPH DEFINITIONS

A graph is called connected if there is a path from any vertex to any other vertex.

A path in a graph is a sequence of distinct vertices, each adjacent to the next.

A cycle in a graph is a path, where the starting and ending vertex are the same.

Page 154: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

GRAPH REPRESENTATIONS

Adjacency Matrix representation

Mixed ( array - linked lists ) representation

Linked lists representation

There are ( at least ) three ways to represent graphs :

Page 155: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

1. ADJACENCY MATRIX REPRESENTATION

Let n denote the number of vertices in a directed graph. We define the adjacency matrix :

boolean[][] am = new boolean[n][n];

am[i][j] is true if and only if vertex i is adjacent to vertex j, i.e., there exists a directed edge from i to j. If the graph is undirected, adjacency matrix will be symmetric.

Page 156: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

1. ADJACENCY MATRIX

1

3 2

0

Directed graph

0 1 1 0

0 0 1 1

0 0 0 0

1 1 1 0

Adjacency matrix

0 1 2 3

0

1

2

3

Page 157: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

In this representation, one-dimensional array is used to represent vertices.

Each entry in that array is a reference to a linked list of vertices adjacent to the vertex represented by array's index.

We assume that vertices are labeled with positive integers starting from zero.

2. MIXED REPRESENTATION

Page 158: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

2. MIXED REPRESENTATION

The same graph as in previous example, would be represented as:

1

3 2

0

Directed graph

0 1

1

2 null3

2 null

2 null

null

0

1

2

3

Mixed representation

Page 159: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

3. LINKED LIST REPRESENTATION

1

1 2

2 0

1

Similar to previous one. Instead of matrix, linked list is used to represent vertices.

2

null

3

null

2

null

3 null0

null

Page 160: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

IMPLEMENTATION

In order to model graphs we need to types of nodes, representing vertices and edges as adjacent vertices.

For the sake of simplicity we will label graph nodes with nonnegative integers.

label EdgeNodeEdgeNode:

label

EdgeNode

VertexNodeVertexNode:

Page 161: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

Edge.java

class Edge { private int label; private Edge next; public Edge() { label = 0; next = null; } public void setLabel(int label) { this.label = label; }

Page 162: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

Edge.java

public int getLabel() { return label; } public void setNextEdge(Edge next) { this.next = next; } public Edge getNextEdge() { return next; }}

Page 163: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

Vertex.javaclass Vertex { private int label; private Vertex nextVertex; private Edge nextEdge; public Vertex() { label = 0; nextVertex = null; nextEdge = null; } public void setLabel(int label) { this.label = label; } public int getLabel() { return label; }

Page 164: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

Vertex.java public void setNextVertex(Vertex nextVertex) { this.nextVertex = nextVertex; } public Vertex getNextVertex() { return nextVertex; } public void setNextEdge(Edge nextEdge) { this.nextEdge = nextEdge; } public Edge getNextEdge() { return nextEdge; }}

Page 165: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

TEST

Our driver class, TestGraph.java will model directed graph:

1

3 2

0e0

e1

e2e3

e4

e5

e6

Page 166: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

TestGraph.javaclass TestGraph { public static void main(String args[]) { Vertex v0 = new Vertex(); Vertex v1 = new Vertex(); Vertex v2 = new Vertex(); Vertex v3 = new Vertex(); Edge e0 = new Edge(); Edge e1 = new Edge(); Edge e2 = new Edge(); Edge e3 = new Edge(); Edge e4 = new Edge(); Edge e5 = new Edge(); Edge e6 = new Edge();

Page 167: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

TestGraph.java

v0.setLabel(0); v1.setLabel(1); v2.setLabel(2); v3.setLabel(3);

e0.setLabel(1); e1.setLabel(2); e2.setLabel(2); e3.setLabel(3); e4.setLabel(0); e5.setLabel(1); e6.setLabel(2);

Page 168: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

TestGraph.java

v0.setNextVertex(v1); v1.setNextVertex(v2); v2.setNextVertex(v3); v0.setNextEdge(e0); e0.setNextEdge(e1); v1.setNextEdge(e2); e2.setNextEdge(e3); v3.setNextEdge(e4); e4.setNextEdge(e5); e5.setNextEdge(e6);

Page 169: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

TestGraph.java

int vertex, edge; Vertex baseVertex = v0; while(baseVertex != null) { vertex = baseVertex.getLabel(); System.out.print("Vertex: " + vertex + " Edges: "); Edge baseEdge = baseVertex.getNextEdge(); while(baseEdge != null) { edge = baseEdge.getLabel(); System.out.print("(" + vertex + "," + edge + ") "); baseEdge = baseEdge.getNextEdge(); } System.out.println(); baseVertex = baseVertex.getNextVertex(); } }}

Page 170: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

GENERAL IMPLEMENTATION

The general implementation requires dynamic creation of vertices and edges, i.e. methods insertVertex() and insertEdge(int, int).

We assume that vertices are labeled with integers starting with zero at the time of their creation.

insertVertex() method is almost identical to the regular insert method in linked lists.

Page 171: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

insertVertex() METHOD

public void insertVertex() { Vertex v = new Vertex(); v.setLabel(vertexLabel); if(vertexLabel == 0) head = v; else tail.setNextVertex(v); tail = v; vertexLabel++; }

Page 172: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

insertEdge(int,int) METHOD

The second method, insertEdge(int u, int v), takes two integers as arguments representing labels of vertices which we want to join.

First of all, we have to check if both vertices exist. If not, edge cannot be inserted. Otherwise, new edge node is created and labeled with v.

Finally, the newly created edge node should be linked to the linked list of adjacent vertices with respect to the vertex node with label u.

Page 173: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

insertEdge(int,int) METHOD public void insertEdge(int u, int v) { Vertex base_u = find(u); Vertex base_v = find(v); if(base_u == null || base_v == null) System.out.println("Cannot insert edge between vertices " + u + " and " + v); else { Edge e = new Edge(); e.setLabel(v); if(base_u.getNextEdge() == null) base_u.setNextEdge(e); else { Edge temp = base_u.getNextEdge(); while(temp.getNextEdge()!= null) temp = temp.getNextEdge(); temp.setNextEdge(e); } } }

Page 174: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

Graph.java

class Graph { private int vertexLabel; private Vertex head; private Vertex tail; public Graph() { vertexLabel = 0; head = tail = null; } public int getSize() { return vertexLabel; }

Page 175: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

Graph.java

public void insertVertex() { Vertex v = new Vertex(); v.setLabel(vertexLabel); if(vertexLabel == 0) head = v; else tail.setNextVertex(v); tail = v; vertexLabel++; }

Page 176: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

Graph.java public void insertEdge(int u, int v) { Vertex base_u = find(u); Vertex base_v = find(v); if(base_u == null || base_v == null) System.out.println("Cannot insert edge between vertices " + u + " and " + v); else { Edge e = new Edge(); e.setLabel(v); if(base_u.getNextEdge() == null) base_u.setNextEdge(e); else { Edge temp = base_u.getNextEdge(); while(temp.getNextEdge()!= null) temp = temp.getNextEdge(); temp.setNextEdge(e); } } }

Page 177: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

Graph.java

public Vertex find(int x) { Vertex base = head; while(base.getLabel() != x) { base = base.getNextVertex(); if(base == null) break; } return base; }

Page 178: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

Graph.java public void print() { int vertex, edge; Vertex baseVertex = head; while(baseVertex != null) { vertex = baseVertex.getLabel(); System.out.print("Vertex: " + vertex + " Edges: "); Edge baseEdge = baseVertex.getNextEdge(); while(baseEdge != null) { edge = baseEdge.getLabel(); System.out.print("(" + vertex + "," + edge + ") "); baseEdge = baseEdge.getNextEdge(); } System.out.println(); baseVertex = baseVertex.getNextVertex(); } }}

Page 179: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

Graph.javaclass TestGraph { public static void main(String args[]) { Graph g = new Graph(); for(int i = 0; i < 4; i++) g.insertVertex(); g.insertEdge(0, 1); g.insertEdge(0, 2); g.insertEdge(1, 2); g.insertEdge(1, 3); g.insertEdge(3, 0); g.insertEdge(3, 1); g.insertEdge(3, 2); g.insertEdge(4, 4);

g.print(); }}

Page 180: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

GRAPH TRAVERSALS

Depth First Search ( DFS )

To traverse graph means to visit all the vertices in some systematic order. Here we will consider Depth First Search (DFS) and Breadth First Search.

DFS is closely related to preorder traversal of a tree. Recall that preorder traversal visits each node before its children.

Preorder (vertex v)1 visit (v);2 for(each child w of v)3 Preorder(w);

Page 181: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

DFS

To turn this into a graph traversal algorithm, we basically replace "child" by "neighbor" (adjacent vertex).

To prevent infinite recursion, we want to visit each vertex once. Here is the algorithm in pseudocode:

DFS(G, source)1 mark all vertices as not visited;2 traverse(vertex v)3 mark v as visited;4 for each neighbor of v5 if neighbor is not marked as visited6 traverse(neighbor);

Page 182: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

DFS DEMO

0

21

4

root

3 5

0 1 3 4 5 2

Page 183: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

IMPLEMENTATION

public void dfs() { System.out.print("dfs: "); boolean visited[] = new boolean[vertexLabel]; for(int i = 0; i < vertexLabel; i++) if(!visited[i]) traverse(i, visited);

System.out.println(); }

Page 184: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

IMPLEMENTATION

private void traverse(int i, boolean visited[]) { if(!visited[i]) { Vertex v = find(i); visited[i] = true; Edge adjacent = v.getNextEdge(); while(adjacent != null) { int index = adjacent.getLabel(); System.out.print("(" + i + " " + index + ") "); adjacent = adjacent.getNextEdge(); traverse(index, visited); } } }

Page 185: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

IMPLEMENTATION

Graph t = new Graph(); for(int i = 0; i < 5; i++) t.insertVertex(); t.insertEdge(1, 0); t.insertEdge(1, 3); t.insertEdge(3, 2); t.insertEdge(3, 4); t.dfs();

Page 186: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

BFS

BFS is a traversal through a graph that finds all the vertices that are reachable from the source vertex.

The order of traversal is such that the algorithm explores all of the neighbors of a vertex before proceeding on the neighbors of its neighbors.

A vertex is discovered the first time it is encountered by the algorithm. A vertex is finished after all of its neighbors are explored.

Page 187: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

BFSThe algorithm in pseudocode is:

BFS(G, source)1 create an empty queue Q;2 label all vertices as not-visited;3 mark the source vertex as visited and place it in Q;4 while(Q is not empty)5 remove the head from Q;6 mark it as visited;7 place its neighbors in the queue;

public void getDataAtHead() { return head.getData(); }

Class Queue requires this method :

Page 188: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

BFS DEMO

0

21

4

root

3 5

0 1 2 3 4 5

Q = {}Q = {0}Q = {1, 2}

Q = {2, 3, 4, 5}Q = {3, 4, 5}Q = {4, 5}Q = {5}

Q = {}

Page 189: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

IMPLEMENTATION

public void bfs() { System.out.print("bfs: "); boolean visited[] = new boolean[vertexLabel]; Queue q = new Queue(); for(int i = 0; i < vertexLabel; i++) if(!visited[i]) { q.enqueue(i); do { int entry = q.getDataAtHead(); if(visited[entry]) q.dequeue();

Page 190: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

IMPLEMENTATION else { visited[entry] = true; q.dequeue(); Vertex v = find(entry); Edge adjacent = v.getNextEdge(); while(adjacent != null) { int index = adjacent.getLabel();

System.out.print("(" + entry + " " + index + ") ");

if(visited[index] == false) q.enqueue(index); adjacent = adjacent.getNextEdge(); } } } while(!q.isEmpty()); } System.out.println(); }

Page 191: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

SHORTEST PATHS

Weighted graph is a graph that has nonnegative integer ( or real number ) associated with each edge.

Let G = ( V, E ) be a weighted directed graph and P = { v0, v1, ..., vk } be a directed path in G as in :

v0 v1 v2 vkw0 w1 w2 wk-1...

We define the weight of path P as a sum of weights of its constituent edges : w(P) = w0 + w1 + ... + wk-1

Page 192: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

SHORTEST PATHS

The shortest path between two vertices u and v is then defined as a path between vertices u and v with minimum weight.

The single-source shortest-path problem is the problem of finding shortest paths between the specified vertex (source) and any other vertex in a weighted directed graph.

Dijkstra's algorithm solves the single-source shortest-path problem for the case in which all edges have nonnegative weights.

Page 193: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

DIJKSTRA’S ALGORITHM

Dutch computer scientist,Turing Award ( 1972 ), ACM ( 2002 )

Graph algorithms, programming languages, Operating Systems

“Referring to computing as computer science is as calling surgery a knife science”Edsger Wybe Dijkstra

(1930-2002)

Page 194: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

DIJKSTRA’S ALGORITHM

Solves the single-source shortest-paths problem for the case in which all edges have nonnegative weights. The algorithm uses the following procedures:

Initialization of a single sourceDistance of the source vertex is set to zero. All other distances are set to infinity.

d[v] denotes the distance from the source vertex and

p[v] denotes the predecessor of vertex v along the shortest path from source.

Page 195: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

INITIALIZATION

In pseudo code initialization looks like :

Init(G, s)1 for each vertex v in G2 set d[v] to INFINITY3 set p[v] to NIL4 set d[s] to 0

Page 196: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

DIJKSTRA’S ALGORITHMRelaxation.The process of relaxing an edge (u, v) consists of testing whether we can improve the shortest path to v found so far by going through u, and if so, updating d[v] and p[v].

s

u

d[v] = 9

d[u] = 5

2v d[u] + w(u,v) < d[v]d[v] = 7

Page 197: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

RELAXATION

In pseudo code relaxation looks like :

Relax(u, v, w)1 if(d[v] > d[u] + w(u, v)2 d[v] = d[u] + w(u, v)3 p[v] = u

Page 198: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

DIJKSTRA’S ALGORITHM

Algorithm maintains a set S of vertices whose final shortest path weights from the source have already been determined.

The algorithm repeatedly selects the vertex u from V - S with the minimum shortest-path estimate, inserts u into S and relaxes all edges leaving u.

Page 199: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

DIJKSTRA’S ALGORITHM

In pseudo code algorithm looks like :

DIJKSTRA(G, w, s)1 Init(G, s)2 S is empty3 Q = V4 while(Q is not empty)5 u = extractMIN(Q)6 add u to S7 for each vertex v adjacent to u8 relax(u, v, w)

Page 200: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

EXAMPLE

0

1

2

3

5

42 2

1

6 3

3

5 3

1

4

0

INF INF

INF INF

INF

S = {}

Q = {0(0), 1(INF), 2(INF), 3(INF), 4(INF), 5(INF)}

Page 201: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

EXAMPLE

0

1

2

3

5

42 2

1

6 3

3

5 3

1

4

0

2 INF

6 INF

INF

S = {0}

Q = {1(6), 2(2), 3(INF), 4(INF), 5(INF)}

Page 202: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

EXAMPLE

S = {0, 2}

Q = {1(6), 3(INF), 4(3), 5(INF)}

3

0

1

2

3

5

42 2

1

6 3

3

5 3

1

4

0

2

6 INF

INF

Page 203: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

EXAMPLE

S = {0, 2, 4}

Q = {1(4), 3(INF), 5(5)}4

5

3

0

1

2

3

5

42 2

1

6 3

3

5 3

1

4

0

2

INF

Page 204: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

EXAMPLE

S = {0, 2, 4, 1}

Q = {3(7), 5(5)}7

3

0

1

2

3

5

42 2

1

6 3

3

5 3

1

4

0

2

4

5

Page 205: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

EXAMPLE

S = {0, 2, 4, 1, 5}

Q = {3(7)}7

3

0

1

2

3

5

42 2

1

6 3

3

5 3

1

4

0

2

4

5

Page 206: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

EXAMPLE

S = {0, 2, 4, 1, 5, 3}

Q = {}7

3

0

1

2

3

5

42 2

1

6 3

3

5 3

1

4

0

2

4

5

Page 207: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

JAVA DATA STRUCTURES

Java provides several interfaces ( collections ) that handle dynamic structures : List <E>, Map <K, V>, Set <E> and Queue <E>

Here we will take a look at List ( LinkedList and ArrayList ).

For more information visit :http://docs.oracle.com/javase/tutorial/collections/interfaces/index.html

Page 208: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

interface List <E>

Defined in java.util package, interface list represents dynamic collection of objects.

It also provides a ListIterator that allows element insertion and replacement.

Some of the known implementing classes are ArrayList, LinkedList, Stack and Vector.

Page 209: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

JavaList.javaimport java.util.List;import java.util.LinkedList;import java.util.Collections;

class JavaList { public static void main(String args[]){ LinkedList<Integer> l = new LinkedList<Integer>();

l.add(3); l.add(1); l.add(5); l.add(4); l.add(2); System.out.println(l);

l.remove(); l.removeLast(); System.out.println(l);

l.remove(1); System.out.println(l);

Page 210: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

JavaList.java l.add(12); l.add(6); l.add(-2); System.out.println(l);

Collections.sort(l); System.out.println(l);

Collections.reverse(l); System.out.println(l);

Integer[] a = l.toArray(new Integer[l.size()]); System.out.println(a);

int[] n = new int[a.length]; for(int i = 0; i < a.length; i++) n[i] = (int)a[i];

System.out.println(n[0]); }}

Page 211: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

ARRAYLIST

Another implementation of interface List.

LinkedList implements List with a doubly linked list.

ArrayList implements List with a dynamically resizing array.

When the original capacity is exceeded, new array ( double in size ) is created and original elements copied to it.

Page 212: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

Deal.javaimport java.util.*;

class Deal { public static void main(String[] args) { if (args.length < 2) { System.out.println("Usage: Deal hands cards"); return; } int numHands = Integer.parseInt(args[0]); int cardsPerHand = Integer.parseInt(args[1]); // Make a normal 52-card deck. String[] suit = new String[] { "spades", "hearts", "diamonds", "clubs" };

Page 213: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

Deal.java

String[] rank = new String[] { "ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "jack", "queen", "king" };

List<String> deck = new ArrayList<String>(); for (int i = 0; i < suit.length; i++) { for (int j = 0; j < rank.length; j++) { deck.add(rank[j] + " of " + suit[i]); } }

Page 214: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

Deal.java

// Shuffle the deck. Collections.shuffle(deck); if (numHands * cardsPerHand > deck.size()) { System.out.println("Not enough cards."); return; } for (int i = 0; i < numHands; i++) System.out.println(dealHand(deck, cardsPerHand)); }

Page 215: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

Deal.java

public static <E> List<E> dealHand(List<E> deck, int n) { int deckSize = deck.size(); List<E> handView = deck.subList(deckSize - n, deckSize); List<E> hand = new ArrayList<E>(handView); handView.clear(); return hand; }}

Page 216: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

ALGORITHM DESIGN

Divide and Conquer algorithm design technique

Merge Sort, Towers of Hanoi

Dynamic Programming algorithm design technique

The Longest Common Subsequence

Greedy algorithm design technique

Activity Selection Problem, Minimum Spanning Trees

Fundamental algorithm design techniques are :

Page 217: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

DIVIDE AND CONQUER

Divide the problem into a number of subproblems.

Conquer the subproblems by solving them recursively.

Combine solutions to subproblems into the solution of the original problem.

Divide and Conquer is a paradigm for designing algorithms which involves three steps at each lever of recursion :

Page 218: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

MERGE SORT

Divide step : Divide the n-element sequence to be sorted into two subsequences of n / 2 elements.

Conquer step : sort the two subsequences recursively.

Combine step : merge the two subsequences to produces the sorted answer.

Merge Sort is divide-and-conquer sorting algorithm which operates intuitively as follows :

Page 219: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

MERGE SORT

6 3 1 7 8 2 5

8 2 56 3 1 7

36 1 7 8 2 5

6 3 1 7 8 2

Page 220: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

MERGE SORT

56 3 1 7 8 2

63 1 7 2 8 5

2 5 81 3 6 7

1 2 3 5 6 7 8

Page 221: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

MergeSort.java

class MergeSort { private int[] a; public MergeSort(int[] a) { this.a = a; } public void sort() { divide(0, a.length - 1); }

Page 222: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

MergeSort.java

public void divide(int p, int r) { int q = (p + r) / 2; if(p < r) { divide(p, q); divide(q + 1, r); merge(p, q, r); } }

Page 223: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

MergeSort.java public void merge(int p, int q, int r) { int merged[] = new int[r - p + 1]; int i = p; int j = q + 1; int k = 0; while(i <= q && j <= r) { if(a[i] <= a[j]) { merged[k] = a[i]; i++; } else { merged[k] = a[j]; j++; } k++; }

Page 224: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

MergeSort.java

while(i <= q) { merged[k] = a[i]; i++; k++; }

while(j <= r) { merged[k] = a[j]; j++; k++; } for(i = p; i <= r; i++) a[i] = merged[i - p]; }

Page 225: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

MergeSort.java

public void print() { for(int i = 0; i < a.length; i++) System.out.print(a[i] + " "); System.out.println(); }}

Page 226: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

TestMergeSort.java

class TestMergeSort { public static void main(String[] args) { int[] a = { 6, 3, 1, 7, 8, 2, 5 }; MergeSort ms = new MergeSort(a); ms.print(); ms.sort(); ms.print(); }}

Page 227: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

ANALYSIS

The running time of recursive function divide() is :

!"#

T(n) = 12T(n / 2) + Θ(merge)

if n = 1if n > 1

Since Θ(merge) is Θ(n), we have :

!"#

T(n) = 12T(n / 2) + Θ(n)

if n = 1if n > 1

By application of Master Theorem we find that the running time of Merge Sort is : T(n) = Θ(n log n)

Page 228: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

TOWERS OF HANOIIn the puzzle Towers of Hanoi the task is to move n disks from peg source to peg dest using auxiliary peg aux.

Only one disk can be moved at a time and bigger disk is not allowed to be placed on top of the smaller disk.

Page 229: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

TOWERS OF HANOI

Our task is to write method move() which solves the puzzle. The task can be summarized as :

move(DISKS, 1, 3, 2);

where 1 denotes the source peg, 3 destination peg, 2 auxiliary peg and DISKS is the number of disks to be moved.

Solution is recursive and focuses on the hard step ( how to move the bottom disk from source to destination? ), not an easy one ( where to move the disk on top? )

Page 230: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

TOWERS OF HANOIThe only way to move the bottom disk from peg 1 to peg 3 is to have remaining disks on peg 2 :

So the original task of moving 3 disks from 1 to 3 is divided into two smaller tasks : moving two disks from 1 to 2 using 3 and moving those two disks from 2 to 3 using 1.

Page 231: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

TOWERS OF HANOI

This can be summarized in code as:

move(2, 1, 2, 3); System.out.println("Move disk from 1 to 3"); move(2, 2, 3, 1);

Assuming that the original call was move(3, 1, 3, 2).

The rest of the problem is done essentially in the same way - the beauty of recursion!

Since the number of disks is smaller by one in each recursive call, recursion stops when number of disks becomes zero.

Page 232: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

Towers.java

class Towers { private int DISKS; public Towers(int n) { DISKS = n; } public void solve() { move(DISKS, 1, 3, 2); }

Page 233: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

Towers.java

public void move(int n, int source, int dest, int aux) { if(n > 0) { move(n - 1, source, aux, dest); System.out.println("Move disk from " + source + " to " + dest); move(n - 1, aux, dest, source); } }}

Page 234: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

TestTowers.java

class TestTowers { public static void main(String[] args) { Towers t = new Towers(3); t.solve(); }}

Page 235: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

ANALYSIS

It can be shown that recursive solution to Towers of Hanoi puzzle produces the best possible solution.

The running time is T(n) = 2T(n - 1) + 1. Solving this recurrence ( homogeneous ) results in O(2n).

For 64 disks, assuming that disk can be moved in one second, it would take 5 × 1011 years to solve the puzzle. The age of the universe is estimated to be 10 billion (1010) years.

Page 236: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

DYNAMIC PROGRAMMING

Dynamic programming paradigm is similar to divide and conquer - it solves problems by combining solutions to subproblems.

The major difference is that subproblems in dynamic programming are dependent, while they are not in the case of divide and conquer.

This technique is typically applied to optimization problems - finding the optimal solution among many solutions.

Page 237: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

DYNAMIC PROGRAMMING

Characterize the structure of an optimal solution.

Recursively define the value of an optimal solution.

Compute the value of an optimal solution.

Construct an optimal solution from computed information.

Typical steps in dynamic programming involve :

Page 238: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

THE LONGEST COMMON SUBSEQUENCE

Before we formally define the LCS problem, we introduce substring and subsequence problems since they all belong to string matching problems.

In its simplest form, the string matching algorithm takes as input two strings, pattern and text, and reports if pattern is contained in text.

Although there are many solutions to string matching problem, here we consider the solution based on finite state automata.

Page 239: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

FINITE STATE AUTOMATA

Q is a finite set of states

q0 is the initial or start state

A ⊆ Q is a distinguished set of accepting states

Σ is a finite alphabet

δ is a function from Q × Σ → Q, called the transition function of M.

Finite state automaton M is a quintuple M = (Q, q0, A, Σ, δ) where :

Page 240: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

0 1 2 3

*-a

a b c

*

*-b

*-c

FINITE STATE AUTOMATA

Finite state automata can be depicted by their transition state diagrams. The one that follows accepts strings that contain “abc” pattern :

Page 241: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

SUBSTRING PROBLEM

a b cx y text

a b c pattern

b x ca y text

a b c pattern

Page 242: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

class Substring { public static void main(String[] args) { if(isSubstring(args[0], args[1])) System.out.println(args[1] + " contains pattern " + args[0]); else System.out.println(args[1] + " does not contain pattern " + args[0]); }

Substring.java

Page 243: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

Substring.java

public static boolean isSubstring(String patt, String text) { int i = 0; int j = 0; while(i < text.length()) { if(j == pattern.length()) break; if(text.charAt(i) == pattern.charAt(j)) j++; else j = 0; i++; }

Page 244: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

Substring.java

if(j == pattern.length()) return true; else return false; }}

Page 245: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

SUBSEQUENCE TESTSubsequence testing is somewhat similar to substring testing. We say that pattern is a subsequence of text, if letters of pattern appear in order, possibly separated.

b x ca y texta b c pattern

Here, pattern “abc” is not a substring of “abxcy”, but a subsequence.

Page 246: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

SUBSEQUENCE TESTAs in the case of substrings, we use finite automata approach. The one that follows accepts strings that contain “abc” subsequence :

0 1 2 3a b c

**-c*-b*-a

Page 247: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

Subsequence.java

class Subsequence { public static void main(String[] args) { if(isSubsequence(args[0], args[1])) System.out.println(args[1] + " contains sequence " + args[0]); else System.out.println(args[1] + " does not contain sequence " + args[0]); }

Page 248: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

Subsequence.java

public static boolean isSubsequence(String patt, String text) { int i = 0; int j = 0; while(i < text.length()) { if(j == pattern.length()) break; if(text.charAt(i) == pattern.charAt(j)) j++; i++; }

Page 249: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

Subsequence.java

if(j == pattern.length()) return true; else return false; }}

Page 250: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

LONGEST COMMON SUBSEQUENCE

Consider pattern “abc” and text “bxycd”. Pattern “abc” is neither a substring nor a subsequence of “bxycd”.

The longest common subsequence of pattern and text in this case is “bc”.

x y cb d texta b c pattern

In the LCS problem, pattern and text have symmetric roles, and will be therefore referred to simply string A and string B.

Page 251: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

DNA sequencingGenes are typically represented as sequences of four letters ACGT corresponding to four submolecules forming DNA. Similarity between two genes is then determined by computing the length of LCS.

File ComparisonThe UNIX diff utility compares two files by finding the LCS between the lines of two files.

LONGEST COMMON SUBSEQUENCE

The major importance of the LCS algorithm is in :

Page 252: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

SOLUTION TO LCS

If the two strings start with the same letter, it is safe to choose that letter as the first character of the subsequence. For example if A = “abc” and B = “acd” we have :

As a first step, we will try to develop recursive solution. Here are some simple facts :

a

a

matchc d

b c

subproblem

Page 253: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

c d

b c

SOLUTION TO LCS

Suppose, the first two characters differ. It is not possible for them to be part of a subsequence - one or the other or both will have to be removed :

b c

d

c

c d

Page 254: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

SOLUTION TO LCS

public int lcs(String A, String B, int i, int j) { if(i == A.length() || j == B.length()) return 0; else if(A.charAt(i) == B.charAt(j)) return 1 + lcs(A, B, i + 1, j + 1); else return max(lcs(A, B, i + 1, j), lcs(A, B, i, j + 1)); }

Here is the code based on recursive algorithm :

Page 255: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

The worst case scenario is when strings are disjoint. Thus the expensive line is :

SOLUTION TO LCS

return max(lcs(A, B, i + 1, j), lcs(A, B, i, j + 1));

Yielding the recurrence T(n) = 2T(n - 1) whose solution is T(n) = O(2n). Not good.

In order to improve efficiency, dynamic programming uses memoization, i.e. intermediate values are stored in the array.

Page 256: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

We define L[i][j] to be the length of LCS for Ai and Bj as :

!"#

L[i][j] =

0L[i - 1][j - 1] + 1

if i = 0 or j = 0if i, j > 0 and A[i] = B[j]

max(L[i][j - 1], L[i - 1][j]) if i, j > 0 and A[i] ≠ B[j]

SOLUTION TO LCS

Once the algorithm terminates, L[m][n] stores the LCS value, where m and n are A’s and B’s lengths respectively.

Page 257: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

0

0 0 00 0 0

0

0

0

b e b d c

a

b

c

0 0 0 0

1 1 1 1 1

1 1 1 1 2

SOLUTION TO LCS

Based on dynamic programming algorithm, this is how the matrix would be filled if A = “abc” and B = “bebdc” :

Page 258: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

LCS.javaclass LCS { public static void main(String[] args) { int n = lcs(args[0], args[1]); System.out.println("LCS: " + n); } public static int lcs(String A, String B) { int m = A.length(); int n = B.length(); int[][] L = new int[m + 1][n + 1]; for(int i = 0; i <= m; i++) L[i][0] = 0; for(int j = 0; j <= n; j++) L[0][j] = 0;

Page 259: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

LCS.java

for(int i = 0; i < m; i++) { for(int j = 0; j < n; j++) { if(A.charAt(i) == B.charAt(j)) L[i + 1][j + 1] = L[i][j] + 1; else L[i + 1][j + 1] = max(L[i + 1][j], L[i][j + 1]); } } return L[m][n]; }

Page 260: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

LCS.java

public static int max(int x, int y) { if(x > y) return x; else return y; }}

Page 261: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

GREEDY ALGORITHMS

Given a set of activities S = { 1, 2, ..., n }, find a maximum size subset A of compatible activities.

Each activity has associated start time si and finish time fi, such that si < fi.

Two activities i and j are compatible if si ≥ fj or sj ≥ fi.

Important class of techniques. Roughly, globa!y optimal solution can be obtained by making loca!y optimal ( greedy ) choices.

Activity Selection Problem

Page 262: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

ACTIVITY SELECTION PROBLEM

0 1 2 3 4 5 6 7 8 9 10 11 time

1s1 f1

2s2 f2

3s3 f3

4s4 f4

5s5 f5

1 3 5

Page 263: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

ActivitySelector.java

class ActivitySelector { public static void main(String[] args) { int[] s = {1, 3, 5, 3, 8}; int[] f = {4, 5, 7, 8, 11}; // sorted LinkedList l = selectActivity(s, f); l.print(); }

Page 264: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

ActivitySelector.java public static LinkedList selectActivity(int[] s,int[] f) { LinkedList l = new LinkedList(); l.insert(1); int j = 1; for(int i = 1; i < s.length; i++) { if(s[i] >= f[j]) { l.insert(i + 1); j = i; } } return l; }}

Page 265: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

ELEMENTS OF GREEDY STRATEGY

It can be proved that Activity Selector always produces optimal solution ( maximum size ).

In many instances, greedy algorithms do not generate optimal solution.

If we applied greedy strategy to the problem of computing the shortest path between A and C, it wouldn’t work. Why?

A

B

D

C10

150

100 10

Page 266: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

ELEMENTS OF GREEDY STRATEGY

The Greedy Choice PropertyProof is required that a greedy choice at each step yields an optimal solution.

Optimal SubstructureA problem exhibits optimal substructure if an optimal solution to the problem contains within it optimal solutions to subproblems.

In order to design a greedy algorithm, the problem must exhibit :

Page 267: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

MINIMUM SPANNING TREES

Spanning Tree T of graph G is a tree that connects all of its vertices.

9

2

15

45

6

14

3

10

8

G

9

2

15

4

14

3 8

T1 (weight: 55)

9

15

46

14

3 8

T2 (weight: 59)

Minimum Spanning Tree is a spanning tree whose weight is minimal.

Page 268: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

PRIM’S ALGORITHM

Choose arbitrary vertex u. Find vertex v adjacent to u such that w(u, v) is minimal. Place that edge into tree T.

Continue adding edges of minimum weight into tree T that are incident to vertices already in a tree and not forming a circuit.

Stop when the number of edges in T is n - 1.

Input : G = 〈 V, E 〉 weighted connected undirected graph with n vertices.Output : T - minimum spanning tree of G.

Page 269: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

PRIM’S ALGORITHM

4

5

3 8

2

9

15

6

14 10

Page 270: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

KRUSKAL’S ALGORITHM

Choose an edge with the minimum weight.

Continue adding edges of minimum weight into tree T that do not form a circuit.

Stop when the number of edges in T is n - 1.

Input : G = 〈 V, E 〉 weighted connected undirected graph with n vertices.Output : T - minimum spanning tree of G.

Page 271: CP2530 - appspot.combranko-cirovic.appspot.com/CP2530/CP2530.Notes.pdf · ANALYSIS OF ALGORITHMS Analysis is more reliable than experimentation. Testing will reveal behaviour for

KRUSKAL’S ALGORITHM

4

5

3 8

2

9

15

6

14 10