Download Elementary Data Structures

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts

Linked list wikipedia , lookup

Array data structure wikipedia , lookup

Transcript
Elementary Data
Structures
Stacks, Queues, & Lists
Amortized analysis
Trees
Abstract Data Types (ADTs)
An abstract data
type (ADT) is an
abstraction of a
data structure
An ADT specifies:



Data stored
Operations on the
data
Error conditions
associated with
operations
Example: ADT modeling a
simple stock trading system


The data stored are buy/sell
orders
The operations supported are
 order buy(stock, shares, price)
 order sell(stock, shares, price)
 void cancel(order)

Error conditions:
 Buy/sell a nonexistent stock
 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
follow the last-in first-out
scheme
Think of a spring-loaded
plate dispenser
Main stack operations:


push(object): inserts an
element
object pop(): removes and
returns the last inserted
element
Auxiliary stack
operations:



Elementary Data Structures
object top(): returns the
last inserted element
without removing it
integer size(): returns the
number of elements
stored
boolean isEmpty():
indicates whether no
elements are stored
5
Exceptions
Attempting the
execution of an
operation of ADT may
sometimes cause an
error condition, called
an exception
Exceptions are said to
be “thrown” by an
operation that cannot
be executed
In the Stack ADT,
operations pop and
top cannot be
performed if the
stack is empty
Attempting the
execution of pop or
top on an empty
stack throws an
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);
active methods with a stack
}
When a method is called, the
foo(int j) {
JVM pushes on the stack a
int k;
frame containing
k = j+1;
 Local variables and return value
7 bar(k);
 Program counter, keeping track of
the statement being executed
….
When a method ends, its frame
}
is popped from the stack and
control is passed to the method 9 bar(int m) {
on top of the stack
…
}
Elementary Data Structures
bar
PC = 9
m=6
foo
PC = 7
j=5
k=6
main
PC = 3
i=5
8
Array-based Stack
A simple way of
implementing the
Stack ADT uses an
array
We add elements
from left to right
A variable keeps
track of the index of
the top element
(size is t+1)
Algorithm size()
return t + 1
Algorithm pop()
if isEmpty() then
throw EmptyStackException
else
tt1
return S[t + 1]
…
S
0 1 2
t
Elementary Data Structures
9
Array-based Stack (cont.)
The array storing the
stack elements may
become full
A push operation will
then throw a
FullStackException


Algorithm push(o)
if t = S.length  1 then
throw FullStackException
else
tt+1
Limitation of the arrayS[t]  o
based implementation
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)
if t = S.length  1 then
can replace the array with
A  new array of
a larger one
size …
How large should the new
for i  0 to t do
array be?
A[i]  S[i]


incremental strategy:
increase the size by a
constant c
doubling strategy: double
the size
Elementary Data Structures
SA
tt+1
S[t]  o
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
The total time T(n) of a series
of n push operations is
proportional to
n + 1 + 2 + 4 + 8 + …+ 2k =
n + 2k + 1 1 = 2n 1
T(n) is O(n)
The amortized time of a push
operation is O(1)
Elementary Data Structures
geometric series
2
4
1
1
8
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
objects
Insertions and deletions follow
the first-in first-out scheme
Insertions are at the rear of the
queue and removals are at the
front of the queue
Main queue operations:


enqueue(object): inserts an
element at the end of the
queue
object dequeue(): removes and
returns the element at the front
of the queue
Auxiliary queue
operations:



object front(): returns the
element at the front without
removing it
integer size(): returns the
number of elements stored
boolean isEmpty(): indicates
whether no elements are
stored
Exceptions

Attempting the execution of
dequeue or front on an
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
modulo operator
(remainder of
division)
Algorithm size()
return (N  f + r) mod N
Algorithm isEmpty()
return (f = r)
Q
0 1 2
f
0 1 2
r
r
Q
f
Elementary Data Structures
23
Queue Operations (cont.)
Operation enqueue
throws an exception if
the array is full
This exception is
implementationdependent
Algorithm enqueue(o)
if size() = N  1 then
throw FullQueueException
else
Q[r]  o
r  (r + 1) mod N
Q
0 1 2
f
0 1 2
r
r
Q
f
Elementary Data Structures
24
Queue Operations (cont.)
Operation dequeue
throws an exception
if the queue is empty
This exception is
specified in the
queue ADT
Algorithm dequeue()
if isEmpty() then
throw EmptyQueueException
else
o  Q[f]
f  (f + 1) mod N
return o
Q
0 1 2
f
0 1 2
r
r
Q
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
Java interface
corresponding to
our Queue ADT
Requires the
definition of class
EmptyQueueException
No corresponding
built-in Java class
public interface Queue {
public int size();
public boolean isEmpty();
public Object front()
throws EmptyQueueException;
public void enqueue(Object o);
public Object dequeue()
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
extends the notion of
array by storing a
sequence of arbitrary
objects
An element can be
accessed, inserted or
removed by specifying
its rank (number of
elements preceding it)
An exception is
thrown if an incorrect
rank is specified (e.g.,
a negative rank)
Main vector operations:
 object elemAtRank(integer r):
returns the element at rank r
without removing it
 object replaceAtRank(integer r,
object o): replace the element at
rank with o and return the old
element
 insertAtRank(integer r, object o):
insert a new element o to have
rank r
 object removeAtRank(integer r):
removes and returns the element
at rank r
Additional operations size() and
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
0 1 2
r
n
0 1 2
o
r
V
V
Elementary Data Structures
n
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
0 1 2
o
r
n
0 1 2
r
n
0 1 2
r
V
V
Elementary Data Structures
n
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
consisting of a sequence
of nodes
Each node stores


next
element
link to the next node
node
elem

A
B
C
Elementary Data Structures
D
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
sequence of positions
storing arbitrary objects
It establishes a
before/after relation
between positions
Generic methods:

size(), isEmpty()
Query methods:

isFirst(p), isLast(p)
Accessor methods:


first(), last()
before(p), after(p)
Update methods:




Elementary Data Structures
replaceElement(p, o),
swapElements(p, q)
insertBefore(p, o),
insertAfter(p, o),
insertFirst(o),
insertLast(o)
remove(p)
41
Doubly Linked List
A doubly linked list provides a natural
implementation of the List ADT
Nodes implement Position and store:



element
link to the previous node
link to the next node
prev
next
elem
node
Special trailer and header nodes
nodes/positions
header
trailer
elements
Elementary Data Structures
42
Insertion
We visualize operation insertAfter(p, X), which returns position q
p
A
B
C
p
A
q
B
C
X
p
A
q
B
Elementary Data Structures
X
C
43
Deletion
We visualize remove(p), where p = last()
p
A
B
C
A
B
C
D
p
D
A
B
Elementary Data Structures
C
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
union of the Vector and
List ADTs
Elements accessed by


List-based methods:

Rank, or
Position
Generic methods:

size(), isEmpty()
Vector-based methods:

elemAtRank(r),
replaceAtRank(r, o),
insertAtRank(r, o),
removeAtRank(r)
first(), last(),
before(p), after(p),
replaceElement(p, o),
swapElements(p, q),
insertBefore(p, o),
insertAfter(p, o),
insertFirst(o),
insertLast(o),
remove(p)
Bridge methods:

Elementary Data Structures
atRank(r), rankOf(p)
46
Applications of Sequences
The Sequence ADT is a basic, generalpurpose, 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
elements
We use a
circular array
storing
positions
A position
object stores:


Element
Rank
Indices f and l
keep track of
first and last
positions
0
1
2
3
positions
S
f
Elementary Data Structures
l
48
Sequence Implementations
Operation
size, isEmpty
atRank, rankOf, elemAtRank
first, last, before, after
replaceElement, swapElements
replaceAtRank
insertAtRank, removeAtRank
insertFirst, insertLast
insertAfter, insertBefore
remove
Elementary Data Structures
Array
1
1
1
1
1
n
1
n
n
List
1
n
1
1
n
n
1
1
1
49
Iterators
An iterator abstracts the
process of scanning through
a collection of elements
Methods of the ObjectIterator
ADT:




object object()
boolean hasNext()
object nextObject()
reset()
Extends the concept of
Position by adding a traversal
capability
Implementation with an array
or singly linked list
An iterator is typically
associated with an another
data structure
We can augment the Stack,
Queue, Vector, List and
Sequence ADTs with method:

ObjectIterator elements()
Two notions of iterator:


snapshot: freezes the
contents of the data
structure at a given time
dynamic: follows changes to
the data structure
Elementary Data Structures
50