Vous êtes sur la page 1sur 50

Elementary Data

Structures
Stacks, Queues, & Lists
Amortized analysis
Trees
Abstract Data Types (ADTs)

An abstract data Example: ADT modeling a


type (ADT) is an simple stock trading system
abstraction of a  The data stored are buy/sell
data structure orders
An ADT specifies:  The operations supported are
 Data stored  order buy(stock, shares, price)
 Operations on the  order sell(stock, shares, price)
data  void cancel(order)
 Error conditions  Error conditions:
associated with  Buy/sell a nonexistent stock
operations
 Cancel a nonexistent order

Elementary Data Structures 2


Stacks
Outline and Reading
The Stack ADT (§2.1.1)
Applications of Stacks (§2.1.1)
Array-based implementation (§2.1.1)
Growable array-based stack (§1.5)

Elementary Data Structures 4


The Stack ADT
The Stack ADT stores
arbitrary objects
Insertions and deletions Auxiliary stack
follow the last-in first-out operations:
scheme  object top(): returns the
Think of a spring-loaded last inserted element
plate dispenser without removing it
Main stack operations:  integer size(): returns the
 push(object): inserts an number of elements
element stored
 object pop(): removes and  boolean isEmpty():
returns the last inserted indicates whether no
element elements are stored

Elementary Data Structures 5


Exceptions

Attempting the In the Stack ADT,


execution of an operations pop and
operation of ADT may top cannot be
sometimes cause an performed if the
error condition, called stack is empty
an exception Attempting the
Exceptions are said to execution of pop or
be “thrown” by an top on an empty
operation that cannot stack throws an
be executed EmptyStackException
Elementary Data Structures 6
Applications of Stacks

Direct applications
 Page-visited history in a Web browser
 Undo sequence in a text editor
 Chain of method calls in the Java Virtual
Machine or C++ runtime environment
Indirect applications
 Auxiliary data structure for algorithms
 Component of other data structures

Elementary Data Structures 7


Method Stack in the JVM
1 main() {
The Java Virtual Machine (JVM) int i = 5;
keeps track of the chain of 3 foo(i); bar
active methods with a stack } PC = 9
When a method is called, the m=6
JVM pushes on the stack a foo(int j) {
frame containing int k; foo
 Local variables and return value k = j+1; PC = 7
 Program counter, keeping track of 7 bar(k); j=5
the statement being executed k=6
When a method ends, its frame ….
is popped from the stack and } main
control is passed to the method 9 bar(int m) { PC = 3
i=5
on top of the stack

}
Elementary Data Structures 8
Array-based Stack

A simple way of Algorithm size()


implementing the return t + 1
Stack ADT uses an
array Algorithm pop()
We add elements if isEmpty() then
from left to right throw EmptyStackException
A variable keeps else
track of the index of tt1
the top element return S[t + 1]
(size is t+1)

S
0 1 2 t
Elementary Data Structures 9
Array-based Stack (cont.)
The array storing the
stack elements may
Algorithm push(o)
become full
if t = S.length  1 then
A push operation will
throw FullStackException
then throw a
FullStackException else
 Limitation of the array- tt+1
based implementation S[t]  o
 Not intrinsic to the
Stack ADT


S
0 1 2 t
Elementary Data Structures 10
Performance and Limitations

Performance
 Let n be the number of elements in the stack
 The space used is O(n)
 Each operation runs in time O(1)
Limitations
 The maximum size of the stack must be defined a
priori and cannot be changed
 Trying to push a new element into a full stack
causes an implementation-specific exception

Elementary Data Structures 11


Growable Array-based Stack

In a push operation, when


the array is full, instead of
throwing an exception, we Algorithm push(o)
can replace the array with if t = S.length  1 then
a larger one A  new array of
size …
How large should the new for i  0 to t do
array be? A[i]  S[i]
 incremental strategy: SA
increase the size by a tt+1
constant c
S[t]  o
 doubling strategy: double
the size
Elementary Data Structures 12
Comparison of the
Strategies

We compare the incremental strategy and


the doubling strategy by analyzing the total
time T(n) needed to perform a series of n
push operations
We assume that we start with an empty
stack represented by an array of size 1
We call amortized time of a push operation
the average time taken by a push over the
series of operations, i.e., T(n)/n
Elementary Data Structures 13
Incremental Strategy Analysis

We replace the array k = n/c times


The total time T(n) of a series of n push
operations is proportional to
n + c + 2c + 3c + 4c + … + kc =
n + c(1 + 2 + 3 + … + k) =
n + ck(k + 1)/2
Since c is a constant, T(n) is O(n + k2), i.e.,
O(n2)
The amortized time of a push operation is O(n)

Elementary Data Structures 14


Doubling Strategy Analysis

We replace the array k = log2 n


times
geometric series
The total time T(n) of a series
of n push operations is 2
proportional to 4
n + 1 + 2 + 4 + 8 + …+ 2k = 1 1
n + 2k + 1 1 = 2n 1
8
T(n) is O(n)
The amortized time of a push
operation is O(1)

Elementary Data Structures 15


Accounting Method Analysis
of the Doubling Strategy
The accounting method determines the amortized
running time with a system of credits and debits
We view a computer as a coin-operated device requiring
1 cyber-dollar for a constant amount of computing.

 We set up a scheme for charging operations. This is


known as an amortization scheme.
 The scheme must give us always enough money to
pay for the actual cost of the operation.
 The total cost of the series of operations is no more
than the total amount charged.
(amortized time)  (total $ charged) / (# operations)

Elementary Data Structures 16


Amortization Scheme for
the Doubling Strategy
Consider again the k phases, where each phase consisting of twice
as many pushes as the one before.
At the end of a phase we must have saved enough to pay for the
array-growing push of the next phase.
At the end of phase i we want to have saved i cyber-dollars, to pay
for the array growth for the beginning of the next phase.
$ $ $ $
$
$ $ $ $
$

0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

• We charge $3 for a push. The $2 saved for a regular push are


“stored” in the second half of the array. Thus, we will have
2(i/2)=i cyber-dollars saved at then end of phase i.
• Therefore, each push runs in O(1) amortized time; n pushes run
in O(n) time.
Elementary Data Structures 17
Queues
Outline and Reading
The Queue ADT (§2.1.2)
Implementation with a circular array
(§2.1.2)
Growable array-based queue
Queue interface in Java

Elementary Data Structures 19


The Queue ADT
The Queue ADT stores arbitrary Auxiliary queue
objects operations:
Insertions and deletions follow  object front(): returns the
the first-in first-out scheme element at the front without
Insertions are at the rear of the removing it
queue and removals are at the  integer size(): returns the
front of the queue number of elements stored
 boolean isEmpty(): indicates
Main queue operations:
whether no elements are
 enqueue(object): inserts an stored
element at the end of the
queue Exceptions
 object dequeue(): removes and  Attempting the execution of
returns the element at the front dequeue or front on an
of the queue empty queue throws an
EmptyQueueException
Elementary Data Structures 20
Applications of Queues
Direct applications
 Waiting lists, bureaucracy
 Access to shared resources (e.g., printer)
 Multiprogramming
Indirect applications
 Auxiliary data structure for algorithms
 Component of other data structures

Elementary Data Structures 21


Array-based Queue
Use an array of size N in a circular fashion
Two variables keep track of the front and rear
f index of the front element
r index immediately past the rear element
Array location r is kept empty

normal configuration
Q
0 1 2 f r

wrapped-around configuration
Q
0 1 2 r f
Elementary Data Structures 22
Queue Operations

We use the Algorithm size()


modulo operator return (N  f + r) mod N
(remainder of
Algorithm isEmpty()
division) return (f = r)

Q
0 1 2 f r
Q
0 1 2 r f

Elementary Data Structures 23


Queue Operations (cont.)

Operation enqueue Algorithm enqueue(o)


throws an exception if if size() = N  1 then
the array is full throw FullQueueException
This exception is else
implementation- Q[r]  o
dependent r  (r + 1) mod N

Q
0 1 2 f r
Q
0 1 2 r f

Elementary Data Structures 24


Queue Operations (cont.)

Operation dequeue Algorithm dequeue()


throws an exception if isEmpty() then
if the queue is empty throw EmptyQueueException
This exception is else
specified in the o  Q[f]
queue ADT f  (f + 1) mod N
return o

Q
0 1 2 f r
Q
0 1 2 r f
Elementary Data Structures 25
Growable Array-based Queue
In an enqueue operation, when the array is
full, instead of throwing an exception, we
can replace the array with a larger one
Similar to what we did for an array-based
stack
The enqueue operation has amortized
running time
 O(n) with the incremental strategy
 O(1) with the doubling strategy

Elementary Data Structures 26


Queue Interface in Java
public interface Queue {
Java interface
corresponding to public int size();
our Queue ADT public boolean isEmpty();
Requires the public Object front()
definition of class throws EmptyQueueException;
EmptyQueueException public void enqueue(Object o);
No corresponding public Object dequeue()
built-in Java class throws EmptyQueueException;
}

Elementary Data Structures 27


Vectors
Outline and Reading
The Vector ADT (§2.2.1)
Array-based implementation (§2.2.1)

Elementary Data Structures 29


The Vector ADT
The Vector ADT Main vector operations:
extends the notion of  object elemAtRank(integer r):

array by storing a returns the element at rank r


without removing it
sequence of arbitrary
 object replaceAtRank(integer r,
objects object o): replace the element at
An element can be rank with o and return the old
accessed, inserted or element
removed by specifying  insertAtRank(integer r, object o):

its rank (number of insert a new element o to have


rank r
elements preceding it)
 object removeAtRank(integer r):
An exception is removes and returns the element
thrown if an incorrect at rank r
rank is specified (e.g., Additional operations size() and
a negative rank) isEmpty()
Elementary Data Structures 30
Applications of Vectors
Direct applications
 Sorted collection of objects (elementary
database)
Indirect applications
 Auxiliary data structure for algorithms
 Component of other data structures

Elementary Data Structures 31


Array-based Vector
Use an array V of size N
A variable n keeps track of the size of the vector
(number of elements stored)
Operation elemAtRank(r) is implemented in O(1)
time by returning V[r]

V
0 1 2 r n

Elementary Data Structures 32


Insertion
In operation insertAtRank(r, o), we need to make
room for the new element by shifting forward the
n  r elements V[r], …, V[n  1]
In the worst case (r = 0), this takes O(n) time

V
0 1 2 r n
V
0 1 2 r n
V o
0 1 2 r n
Elementary Data Structures 33
Deletion
In operation removeAtRank(r), we need to fill the
hole left by the removed element by shifting
backward the n  r  1 elements V[r + 1], …, V[n  1]
In the worst case (r = 0), this takes O(n) time

V o
0 1 2 r n
V
0 1 2 r n
V
0 1 2 r n
Elementary Data Structures 34
Lists and Sequences
Outline and Reading
Singly linked list
Position ADT and List ADT (§2.2.2)
Doubly linked list (§ 2.2.2)
Sequence ADT (§ 2.2.3)
Implementations of the sequence ADT
(§ 2.2.3)
Iterators (2.2.3)

Elementary Data Structures 36


Singly Linked List
A singly linked list is a
concrete data structure next
consisting of a sequence
of nodes
Each node stores
 element elem node
 link to the next node

A B C D

Elementary Data Structures 37


Stack with a Singly Linked List
We can implement a stack with a singly linked list
The top element is stored at the first node of the list
The space used is O(n) and each operation of the
Stack ADT takes O(1) time

nodes

t 

elements
Elementary Data Structures 38
Queue with a Singly Linked List
We can implement a queue with a singly linked list
 The front element is stored at the first node
 The rear element is stored at the last node
The space used is O(n) and each operation of the
Queue ADT takes O(1) time r
nodes

f 

elements
Elementary Data Structures 39
Position ADT
The Position ADT models the notion of
place within a data structure where a
single object is stored
It gives a unified view of diverse ways
of storing data, such as
 a cell of an array
 a node of a linked list
Just one method:
 object element(): returns the element
stored at the position

Elementary Data Structures 40


List ADT
The List ADT models a Accessor methods:
sequence of positions  first(), last()
storing arbitrary objects  before(p), after(p)
It establishes a Update methods:
before/after relation  replaceElement(p, o),
between positions swapElements(p, q)
Generic methods:  insertBefore(p, o),
insertAfter(p, o),
 size(), isEmpty()
 insertFirst(o),
Query methods: insertLast(o)
 isFirst(p), isLast(p)  remove(p)

Elementary Data Structures 41


Doubly Linked List
A doubly linked list provides a natural prev next
implementation of the List ADT
Nodes implement Position and store:
 element
link to the previous node elem

node
 link to the next node
Special trailer and header nodes

header nodes/positions trailer

elements
Elementary Data Structures 42
Insertion
We visualize operation insertAfter(p, X), which returns position q
p

A B C
p

A B q C

X
p q

A B X C
Elementary Data Structures 43
Deletion
We visualize remove(p), where p = last()
p

A B C D

A B C p

A B C
Elementary Data Structures 44
Performance
In the implementation of the List ADT
by means of a doubly linked list
 The space used by a list with n elements is
O(n)
 The space used by each position of the list
is O(1)
 All the operations of the List ADT run in
O(1) time
 Operation element() of the
Position ADT runs in O(1) time
Elementary Data Structures 45
Sequence ADT
The Sequence ADT is the List-based methods:
union of the Vector and  first(), last(),
List ADTs before(p), after(p),
Elements accessed by replaceElement(p, o),
 Rank, or swapElements(p, q),
 Position insertBefore(p, o),
insertAfter(p, o),
Generic methods: insertFirst(o),
 size(), isEmpty() insertLast(o),
Vector-based methods: remove(p)
 elemAtRank(r), Bridge methods:
replaceAtRank(r, o),
insertAtRank(r, o),  atRank(r), rankOf(p)
removeAtRank(r)

Elementary Data Structures 46


Applications of Sequences
The Sequence ADT is a basic, general-
purpose, data structure for storing an ordered
collection of elements
Direct applications:
 Generic replacement for stack, queue, vector, or
list
 small database (e.g., address book)
Indirect applications:
 Building block of more complex data structures

Elementary Data Structures 47


Array-based Implementation
We use a elements
circular array
storing
positions
A position
object stores:
 Element 0 1 2 3
 Rank
Indices f and l positions
keep track of
first and last
positions S
f l
Elementary Data Structures 48
Sequence Implementations
Operation Array List
size, isEmpty 1 1
atRank, rankOf, elemAtRank 1 n
first, last, before, after 1 1
replaceElement, swapElements 1 1
replaceAtRank 1 n
insertAtRank, removeAtRank n n
insertFirst, insertLast 1 1
insertAfter, insertBefore n 1
remove n 1
Elementary Data Structures 49
Iterators
An iterator abstracts the An iterator is typically
process of scanning through associated with an another
a collection of elements data structure
Methods of the ObjectIterator We can augment the Stack,
ADT:
Queue, Vector, List and
 object object()
Sequence ADTs with method:
 boolean hasNext()
 ObjectIterator elements()
 object nextObject()
 reset() Two notions of iterator:
Extends the concept of  snapshot: freezes the
Position by adding a traversal contents of the data
capability structure at a given time
Implementation with an array  dynamic: follows changes to
or singly linked list the data structure

Elementary Data Structures 50

Vous aimerez peut-être aussi