Download as pdf or txt
Download as pdf or txt
You are on page 1of 63

CS1006T Data Structures

Array-based Implementation of List

Chandrabose Aravindan
<AravindanC@ssn.edu.in>

Professor of Information Technology


SSN College of Engineering

April 02, 2024

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 1 / 27


Array and List

44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
21
21
21
21
21
21
21
21
21
21
21
21
21
21
21
21
21
snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 2 / 27


21 21
44 44
21 21
45 45
21 21

C. Aravindan (SSN)
Array and List

46 46

0
S
21 21
47 47
21 21
48 48

1
A
21 21
49 49
21 21
50 50

2
M 21
51
21
51
21 21
3 52 52
P

21 21

Data Structures
53 53
21 21
54 54
4
L

21 21
55 55
21 21
56 56
5
E

21 21
57 57
21 21
58 58
21 21
59 59
April 02, 2024

21 21
60 60
snu-logo

2 / 27
Array and List

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 3 / 27


Typed Array

from a r r a y i m p o r t a r r a y

class ArrayList :

d e f __init__ ( s e l f , cap =16):


s e l f . _size = 0
s e l f . _ c a p a c i t y = cap
s e l f . _items = a r r a y ( ’ i ’ , [ 0 ] ∗ s e l f . _capacity )

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 4 / 27


Referential Array

But, this is nowhere close the list in Python!

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 5 / 27


Referential Array

But, this is nowhere close the list in Python!

'Janet' 'Jonas'
'Joseph' 'Helen'

'Rene' 'Virginia'

0 1 2 3 4 5

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 5 / 27


Referential Array

We may use the low-level ‘ctypes’ package in python, to create a


referential array

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 6 / 27


Referential Array

We may use the low-level ‘ctypes’ package in python, to create a


referential array
However, the size must the static!

import ctypes

class ArrayList :

d e f __init__ ( s e l f , cap =16):


s e l f . _size = 0
s e l f . _ c a p a c i t y = cap
s e l f . _ i t e m s = ( c t y p e s . p y _ o b j e c t ∗ cap ) ( )

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 6 / 27


Iterator

Python automatically provides iterator when ‘__len__()’ and


‘__getitem__()’ methods are defined

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 7 / 27


Iterator

Python automatically provides iterator when ‘__len__()’ and


‘__getitem__()’ methods are defined

class ArrayList :

d e f __len__ ( s e l f ) :
return s e l f . _size

d e f __getitem__ ( s e l f , i n d e x ) :
i f ( n o t 0 <= i n d e x < s e l f . _ s i z e ) :
r a i s e I n d e x E r r o r ( " Index ␣ i s ␣ out ␣ of ␣ range ! " )
r e t u r n s e l f . _items [ i n d e x ]

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 7 / 27


Just for academic purpose

In python, “traditional” ‘isEmpty()’ method is not required (why?)

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 8 / 27


Just for academic purpose

In python, “traditional” ‘isEmpty()’ method is not required (why?)

class ArrayList :

def isEmpty ( s e l f ) :
" " " T h i s method i s a c t u a l l y n o t r e q u i r e d .
Defined only f o r academic purpose .
D e f i n i t i o n o f __len__ e n s u r e s t h a t b o o l ( l s t )
is defined !
"""
r e t u r n ( s e l f . _ s i z e == 0 )

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 8 / 27


Just for academic purpose

In python, “traditional” position methods are NOT required for a list


iterator. We may define them for academic purpose only.

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 9 / 27


Just for academic purpose

In python, “traditional” position methods are NOT required for a list


iterator. We may define them for academic purpose only.

class ArrayList :

def begin ( s e l f ) :
return 0

d e f end ( s e l f ) :
return s e l f . _size

d e f next ( s e l f , pos ) :
i f ( n o t 0 <= i n d e x < s e l f . _ s i z e ) :
r a i s e I n d e x E r r o r ( " Index ␣ i s ␣ out ␣ of ␣ range ! " )
r e t u r n ( po s + 1 )
snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 9 / 27


Insertion and Deletion?

What about insertion and deletion?

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 10 / 27


Inserting at the end position

Inserting at the end position should be easy! (similar to ‘append()’


method in python list)

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 11 / 27


Inserting at the end position

Inserting at the end position should be easy! (similar to ‘append()’


method in python list)

d e f append ( s e l f , i t e m ) :
s e l f . _items [ s e l f . _ s i z e ] = item
s e l f . _ s i z e += 1

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 11 / 27


Inserting at the end position

What about the capacity constraint?

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 12 / 27


Inserting at the end position

What about the capacity constraint?

class ArrayList :

d e f append ( s e l f , i t e m ) :
i f ( s e l f . _ s i z e == s e l f . _ c a p a c i t y ) :
raise IndexError ( ’ List ␣ is ␣ already ␣ f u l l ! ’ )
s e l f . _items [ s e l f . _ s i z e ] = item
s e l f . _ s i z e += 1

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 12 / 27


Dynamic Array

Let us NOT impose a capacity limit on our list!

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 13 / 27


Dynamic Array

Let us NOT impose a capacity limit on our list!


We will dynamically resize the array to get away with the capacity
concept!

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 13 / 27


Dynamic Array

Let us NOT impose a capacity limit on our list!


We will dynamically resize the array to get away with the capacity
concept!

A A

B B A

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 13 / 27


Dynamic Array

Let us use a private method to ‘resize‘ the array whenever it is


necessary.

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 14 / 27


Dynamic Array

Let us use a private method to ‘resize‘ the array whenever it is


necessary.

class ArrayList :

d e f append ( s e l f , i t e m ) :
i f ( s e l f . _ s i z e == s e l f . _ c a p a c i t y ) :
s e l f . _ r e s i z e (2 ∗ s e l f . _capacity )
s e l f . _items [ s e l f . _ s i z e ] = item
s e l f . _ s i z e += 1

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 14 / 27


Resizing the Array

The algorithm for resizing is easy to implement in python

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 15 / 27


Resizing the Array

The algorithm for resizing is easy to implement in python


But, what is the complexity of doing this?

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 15 / 27


Resizing the Array

The algorithm for resizing is easy to implement in python


But, what is the complexity of doing this?

class ArrayList :

def _resize ( self , capacity ) :


temp = ( c t y p e s . p y _ o b j e c t ∗ c a p a c i t y ) ( )
f o r index in range ( s e l f . _size ) :
temp [ i n d e x ] = s e l f . _ i t e m s [ i n d e x ]
s e l f . _ i t e m s = temp
s e l f . _capacity = capacity

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 15 / 27


Amortized Analysis

Most of the time, the ‘append()’ method runs in constant time O(1)

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 16 / 27


Amortized Analysis

Most of the time, the ‘append()’ method runs in constant time O(1)
Occasionally, resizing is required and the complexity is O(n)

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 16 / 27


Amortized Analysis

Most of the time, the ‘append()’ method runs in constant time O(1)
Occasionally, resizing is required and the complexity is O(n)
In such cases, amortized analysis provides a better upper bound

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 16 / 27


Amortized Analysis

Most of the time, the ‘append()’ method runs in constant time O(1)
Occasionally, resizing is required and the complexity is O(n)
In such cases, amortized analysis provides a better upper bound
Analyze the time complexity for m successive operations and amortize
the time equally for each individual operation.

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 16 / 27


Amortized Analysis
Suppose basic append operation (without resizing) costs us $1, we
will actually charge $3 and save $2

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 17 / 27


Amortized Analysis
Suppose basic append operation (without resizing) costs us $1, we
will actually charge $3 and save $2
When the array size is 2i−1 , resizing happens for additional 2i−1 items
(total capacity 2i )

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 17 / 27


Amortized Analysis
Suppose basic append operation (without resizing) costs us $1, we
will actually charge $3 and save $2
When the array size is 2i−1 , resizing happens for additional 2i−1 items
(total capacity 2i )
If we add amortized cost of $2 for each subsequent appends, we would
have saved 2i−1 ∗ 2 = 2i , which is sufficient for the next expansion!

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 17 / 27


Amortized Analysis
Suppose basic append operation (without resizing) costs us $1, we
will actually charge $3 and save $2
When the array size is 2i−1 , resizing happens for additional 2i−1 items
(total capacity 2i )
If we add amortized cost of $2 for each subsequent appends, we would
have saved 2i−1 ∗ 2 = 2i , which is sufficient for the next expansion!
$ $ $ $
$ $ $ $

0 1 2 3 4 5 6 7

$
$

snu-logo
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
C. Aravindan (SSN) Data Structures April 02, 2024 17 / 27
Amortized Analysis
Consider a dynamic array based implementation of List ADT, with
initial array capacity of 1, which is doubled when required

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 18 / 27


Amortized Analysis
Consider a dynamic array based implementation of List ADT, with
initial array capacity of 1, which is doubled when required
The total time to perform a series of n append operations, starting
from an empty list, is O(n)

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 18 / 27


Amortized Analysis
Consider a dynamic array based implementation of List ADT, with
initial array capacity of 1, which is doubled when required
The total time to perform a series of n append operations, starting
from an empty list, is O(n)
Thus, amortized cost for each append operation is O(1)

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 18 / 27


Amortized Analysis
Consider a dynamic array based implementation of List ADT, with
initial array capacity of 1, which is doubled when required
The total time to perform a series of n append operations, starting
from an empty list, is O(n)
Thus, amortized cost for each append operation is O(1)
primitive operations for an append

snu-logo
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
current number of elements
C. Aravindan (SSN) Data Structures April 02, 2024 18 / 27
Geometric Vs Arithmetic Progressions
The fact that the capacity of the array is geometrically increasing is
important!

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 19 / 27


Geometric Vs Arithmetic Progressions
The fact that the capacity of the array is geometrically increasing is
important!
An arithmetic increase of capacity will lead to an amortized cost of
O(n)

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 19 / 27


Geometric Vs Arithmetic Progressions
The fact that the capacity of the array is geometrically increasing is
important!
An arithmetic increase of capacity will lead to an amortized cost of
O(n)

primitive operations for an append

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
current number of elements snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 19 / 27


Geometric Vs Arithmetic Progressions

Suppose the resizing strategy is to increase the capacity by a fixed


value c > 0

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 20 / 27


Geometric Vs Arithmetic Progressions

Suppose the resizing strategy is to increase the capacity by a fixed


value c > 0
n successive appends will result in resizing cost of
c + 2c + 3c + · · · + mc, where m = ⌈n/c⌉

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 20 / 27


Geometric Vs Arithmetic Progressions

Suppose the resizing strategy is to increase the capacity by a fixed


value c > 0
n successive appends will result in resizing cost of
c + 2c + 3c + · · · + mc, where m = ⌈n/c⌉
This is clearly O(n2 ), and so amortized cost for each append is O(n)

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 20 / 27


Inserting at an arbitrary position

How can we insert an object at an arbitrary position 0 ≤ k ≤ _size ?

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 21 / 27


Inserting at an arbitrary position

How can we insert an object at an arbitrary position 0 ≤ k ≤ _size ?

0 1 2 k n−1

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 21 / 27


Inserting at an arbitrary position

It should be easy to implement this idea in Python

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 22 / 27


Inserting at an arbitrary position

It should be easy to implement this idea in Python

class ArrayList :

def i n s e r t ( s e l f , index , item ) :


i f ( n o t 0 <= i n d e x <= s e l f . _ s i z e ) :
r a i s e I n d e x E r r o r ( " Index ␣ i s ␣ out ␣ of ␣ range ! " )
i f ( s e l f . _ s i z e == s e l f . _ c a p a c i t y ) :
s e l f . _ r e s i z e (2 ∗ s e l f . _capacity )
f o r i i n r a n g e ( s e l f . _ s i z e , i n d e x , −1):
s e l f . _ i t e m s [ i ] = s e l f . _ i t e m s [ i −1]
s e l f . _items [ i n d e x ] = item
s e l f . _ s i z e += 1

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 22 / 27


Deleting at an arbitrary position

How can we delete an object at an arbitrary position 0 ≤ k < _size ?

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 23 / 27


Deleting at an arbitrary position

How can we delete an object at an arbitrary position 0 ≤ k < _size ?

0 1 2 k n−1

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 23 / 27


Deleting at an arbitrary position

It should be easy to implement this idea in Python

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 24 / 27


Deleting at an arbitrary position

It should be easy to implement this idea in Python

class ArrayList :

def delete ( self , index ) :


i f ( n o t 0 <= i n d e x < s e l f . _ s i z e ) :
r a i s e I n d e x E r r o r ( " Index ␣ i s ␣ out ␣ of ␣ range ! " )
f o r i in range ( index , s e l f . _size − 1 ) :
s e l f . _ i t e m s [ i ] = s e l f . _ i t e m s [ i +1]
s e l f . _ s i z e −= 1
s e l f . _ i t e m s [ s e l f . _ s i z e ] = None
i f ( s e l f . _ s i z e < ( s e l f . _ c a p a c i t y // 4 ) ) :
s e l f . _ r e s i z e ( s e l f . _ c a p a c i t y // 2 )

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 24 / 27


Time Complexity of Insertion and Deletion

Both insertion and deletion at arbitrary positions are of linear time


complexity (O(n))

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 25 / 27


Time Complexity of Insertion and Deletion

Both insertion and deletion at arbitrary positions are of linear time


complexity (O(n))
This is inherent drawback of array-based implementation of lists

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 25 / 27


Time Complexity of Insertion and Deletion

Both insertion and deletion at arbitrary positions are of linear time


complexity (O(n))
This is inherent drawback of array-based implementation of lists
It may be better to go for linked-lists if these arbitrary insertions and
deletions are frequently required

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 25 / 27


Time Complexity of Insertion and Deletion

Both insertion and deletion at arbitrary positions are of linear time


complexity (O(n))
This is inherent drawback of array-based implementation of lists
It may be better to go for linked-lists if these arbitrary insertions and
deletions are frequently required
We have seen earlier that searching for an item is also of linear
complexity (the average case is also O(n))

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 25 / 27


Time Complexity of Insertion and Deletion

Both insertion and deletion at arbitrary positions are of linear time


complexity (O(n))
This is inherent drawback of array-based implementation of lists
It may be better to go for linked-lists if these arbitrary insertions and
deletions are frequently required
We have seen earlier that searching for an item is also of linear
complexity (the average case is also O(n))
This is inherent drawback of a linear structure

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 25 / 27


Time Complexity of Insertion and Deletion

Both insertion and deletion at arbitrary positions are of linear time


complexity (O(n))
This is inherent drawback of array-based implementation of lists
It may be better to go for linked-lists if these arbitrary insertions and
deletions are frequently required
We have seen earlier that searching for an item is also of linear
complexity (the average case is also O(n))
This is inherent drawback of a linear structure
Later, we will look at tree structures to perform efficient search

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 25 / 27


Time Complexity of Insertion and Deletion

Both insertion and deletion at arbitrary positions are of linear time


complexity (O(n))
This is inherent drawback of array-based implementation of lists
It may be better to go for linked-lists if these arbitrary insertions and
deletions are frequently required
We have seen earlier that searching for an item is also of linear
complexity (the average case is also O(n))
This is inherent drawback of a linear structure
Later, we will look at tree structures to perform efficient search
Hashing is another technique that is frequently used to improve the
search efficiency

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 25 / 27


Summary

We have discussed an array based implementation of List ADT

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 26 / 27


What next?

What is the complexity of our ‘append()’, ‘insert()’, and ‘delete()’


methods?
We will explore other implementations of List ADT
We will look at some of the applications of Lists
Later we will discuss implementations of Stack ADT and Queue ADT,
and their applications

snu-logo

C. Aravindan (SSN) Data Structures April 02, 2024 27 / 27

You might also like