0% found this document useful (0 votes)
100 views

03-Example - Stackspan PDF

This document discusses data structures and algorithms for stacks and queues. It describes using a growable array-based stack that dynamically resizes the underlying array when it becomes full. Two strategies for resizing are discussed: the tight strategy, which increases the array size by a constant; and the growth strategy, which doubles the array size. The growth strategy is more efficient, with a runtime of O(n) compared to O(n^2) for the tight strategy. The document also provides an example of using a stack to efficiently compute the spans of stock prices in O(n) time, as opposed to the naive quadratic algorithm.

Uploaded by

Ray Jia
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
100 views

03-Example - Stackspan PDF

This document discusses data structures and algorithms for stacks and queues. It describes using a growable array-based stack that dynamically resizes the underlying array when it becomes full. Two strategies for resizing are discussed: the tight strategy, which increases the array size by a constant; and the growth strategy, which doubles the array size. The growth strategy is more efficient, with a runtime of O(n) compared to O(n^2) for the tight strategy. The document also provides an example of using a stack to efficiently compute the spans of stock prices in O(n) time, as opposed to the naive quadratic algorithm.

Uploaded by

Ray Jia
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 20

CSI2110

Data Structures
and Algorithms

1
Trying to overcome the
limitations of Array based
Stacks and Queues

A Growable Array-Based Stack


Two strategies:
tight strategy
growth strategy
A full Growth Strategy

Create B
B

Copy A into B

Reassign reference A to
the new array

A
A Growable Array-Based Stack
Idea: when the array S is full, replace it with a larger one and continue
processing push operations.

Algorithm push(obj):
if size() = N then
A ← new array of length f(N)
for i ← 0 to N - 1
A[i] ← S[i]
S ← A
t ← t + 1
S[t] ← obj
• How large should the new array be?
– tight strategy (add a constant): f(N) = N + c

– growth strategy (double up): f(N) = 2N


Tight vs. Growth Strategies:
a comparison

• To compare the two strategies, we use the following cost model:

OPERATION RUN TIME


regular push operation: add one element 1
special push operation: create an array of f(N)+N+1
size f(N), copy N elements, and add one
element
Tight Strategy (c=4)
f(N) = N + c = N + 4
push phase N cost
1 1 0 5
2 1 4 1
• start with an array 3 1 4 1
4 1 4 1
of size 0 5 2 4 13
• the cost of a special 6 2 8 1
7 2 8 1
push is 8 2 8 1
f(N)+N+1 = 2N + 5 9 3 8 21
10 3 12 1
=N+c+N+1 11 3 12 1
= 2N + c + 1 in general 12 3 12 1
13 4 12 29
c =4 push phase N cost
1 1 0 5
5 = 2N + c + 1 = c+1 2 1 4 1
1 3 1 4 1
1 c-1 4 1 4 1
1 5 2 4 13
13 = 6 2 8 1
1 2c+c+1 7 2 8 1
Now N = c
1 8 2 8 1
1 9 3 8 21
21 10 3 12 1
1 11 3 12 1
1 12 3 12 1
Now N = 2c = 2 (2 c) + c + 1
1 13 4 12 29

Phase 1: c+1 + (c-1) = 2c

Phase 2: 2 c + c + 1 + (c-1) = 4c

Phase 3: 2 (2 c) + c + 1 + (c-1) = 6c Phase i = 2ci


Performance of the Tight Strategy

• We consider k phases, where k = n/c


• Each phase corresponds to a new array size
• The cost of phase i is 2ci
• The total cost of n push operations is the total cost
of k phases, with k = n/c:
2c (1 + 2 + 3 + ... + k),
which is O(k2) and O(n2).
Growth Strategy
(double up): f(N) = 2N
• start with an array of push phase N cost
size 0, then 1, 2, 4, 8, 1 0 0 1
... 2 1 1 4
3 2 2 7
• the cost of a special
4 2 4 1
push is
5 3 4 13
f(N)+N+1 = 6 3 8 1
2N + N + 1 = 7 3 8 1
3N + 1 8 3 8 1
for N>0 9 4 8 25
10 4 16 1
11 4 16 1
12 4 16 1
... ... ... ...
16 4 16 1
17 5 16 49
Phase i > 1
push phase N cost
Special 1 0 0 1
Normal 2 1 1 4
3 2 2 7

4 2 4 1
Normal 2 i-1
5 3 4 13
6 3 8 1
7 3 8 1
8 3 8 1
9 4 8 25
Cost of special operations: 3N + 1 10 4 16 1
11 4 16 1
Phase 0: 1 0+1 12 4 16 1
Phase 1: 4 ... ... ... ...
3•1+1
Phase 2: 7 16 4 16 1
Phase 3: 13 3•2+1
17 5 16 49
3•4+1

Phase i: 3•2 i-1 +1 TOT Phase i: 2 i-1 +3•2 i-1 +1

= 2 i+1
Growth Strategy

Total cost Phase i:


3 2i-1 + 1 + 2i-1 -1 = 2i+1

HOW MANY PHASES


TO PERFORM n pushes ?

2i-1 push in phase i,

Phase 0 From phase 1

???

n = 1+ Σ 1 2i-1

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 n
Performance of the Growth Strategy

• We consider k phases, where k = log n


• Each phase corresponds to a new array size
• The cost of phase i is 2 i + 1
• The total cost of n push operations is the total cost of k phases, with k =
log n
• 2 + 4 + 8 + ... + 2 log n + 1 = 2 ( 1 + 2 + … + 2 log n )
= 2((2log n +1-1)/(2-1)) = 2 ( 2(n) – 1) ) = 4n - 2

• m
• S = ∑ ri = 1 + r + r2 + … + rm = (rm+1-1)/(r-1)
i=0

•b=a log b
a -> b = 2 log b -> n=2 log n

• The growth strategy wins! O(n)


Another Example of the
use of a Stack
Computing Spans
Given a series of n daily price quotes for a stock, we call the span
of the stock’s price on a certain day the maximum number of
consecutive days up to the current day that the price of the stock
has been less than or equal to its price on that day.
Computing Spans
8
• Stack as an auxiliary data
structure in an algorithm 6
• Given an an array X, the span 5
S[i] of X[i] is the maximum
number of consecutive 3
elements X[j] immediately
preceding X[i] and such that
2
X[j] ≤ X[i] 0
• Spans have applications to 0 1 2 3 4
financial analysis
– E.g., stock at 52-week high
X 6 3 4 5 2

S 1 1 2 3 1
Quadratic Algorithm
Algorithm spans1(X, n)
Input array X of n integers
Output array S of spans of X #
S ← new array of n integers n
for i ← 0 to n − 1 do n
s←1 n
while s ≤ i ∧ X[i − s] ≤ X[i] 1 + 2 + …+ (n − 1)
s←s+1 1 + 2 + …+ (n − 1)
S[i] ← s n
return S 1

• Algorithm spans1 runs in O(n2) time


Computing Spans with a Stack
Closest higher element
preceding i
X
8
j
6 Day i

5 Si = i– j
3
2
0
0 1 2 3 4 5 6 7
X
8
6
5
Index: 0, 1, 2, 3, 4, 5, 6, 7
3 X : 6, 3, 4, 1, 2, 3, 5, 4
S : 1, 1, 2, 1, 2, 3, 6, 1
2
0
0 1 2 3 4 5 6 7

1 (3)
0 (6)
2(4) 3(1)
0(6) 2(4) 4(2)
0(6) 2(4)
0(6)
• We keep in a stack the indices of the elements visible when “looking
back”

• We scan the array from left to right


– Let i be the current index

– We pop indices from the stack until we find index j such


that
X[j] > X[i]

– We set S[i] ← i - j

– We push i onto the stack


Linear Algorithm
Algorithm computeSpans2(P):
• Each index of the array
Input: an n-element array P of numbers
– Is pushed into the representing stock prices
stack exactly one
Output: an n-element array S of numbers such
– Is popped from the that S[i] is the span of the stock on day i
stack at most once
Let D be an empty stack
• The statements in the
while-loop are executed at for i ←0 to n - 1 do k ← 0
most n times done ← false
• Algorithm spans2 runs in while not(D.isEmpty() or done) do
O(n) time if P[i] ≥ P[D.top()] then
D.pop()
else done ← true
if D.isEmpty() then h ← -1
else h ← D.top()
S[i] ← i - h
D.push(i)
return S

You might also like