[SOLVED] CS201 Homework 2

30.00 $

Category:

Description

1/5 - (1 vote)

Dynamic List ADT

In this assignment, you will implement a dynamic list ADT in Python that allows for inserting and deleting

elements at a specified index and retrieving elements at a specified index. The list should be implemented

as both a dynamic array and a linked list.

1 Implementation Details and Tasks

❼ Implement the DynamicArrayList and LinkedList classes in the accompanying file, listadt.py, in

the accompanying src/ sub-folder.

❼ In the DynamicArrayList and LinkedList classes, implement the following methods:

insert(index, value): inserts value at the specified index

delete(index): deletes the element at the specified index

get(index): returns the element at the specified index

size(): returns the number of elements in the list

display(): returns the string representation of the list

❼ The dynamic array should be implemented using Python arrays. Upon creation, the dynamic array

will have a size of one, and all empty items will be initialised as -1.

❼ The dynamic array should dynamically resize itself when necessary to ensure efficient use of memory

i.e., the array should double it’s size when it is full and reduce by half once it is quarter

the size of array.

❼ The cost of resizing the array should be linear in the size of the array.

❼ The linked list should be implemented as a singly linked list.

❼ The program should take as an input a file that specifies which data structure should be used to

implement the dynamic list ADT and which operations should be performed on the list.

❼ The program should read the input file, create the appropriate data structure, and perform the specified

operations. The program should then output the result of each operation.

❼ The function load which parses the input file and saves the output of the program to a given file, has

already been implented in the accompanying file, listadt.py, in the accompanying src/ sub-folder.

1CS 201, Spring 2023 HW 2: Skiplists and Dynamic List ADT L5 – Group 3

1.1 Input and Output

The input file will specify which data structure should be used to implement the Dynamic List ADT and

which operations should be performed on the list. The input file will have the following format:

<data s t r u c t u r e >

<o p e r a ti o n> <arg1> <arg2>

data structureis either array or linkedlist, indicating which data structure should be used to

implement the Dynamic List ADT

operationis one of the following:

– insert: Insert an item into the list. The arg1is the index at which to insert the item and arg2

is the item to be inserted.

– delete: Delete an item from the list. The arg1is the index of the item to be deleted.

– get: Return the item at the specified index in the list. The arg1is the index of the item to be

returned.

– size: Return the number of items in the list.

– display: Return the string representation of the list.

The output of the program will be the result of each operation, one per line.

1.2 Example

In the following examples, the input file specifies which data structure should be used to implement the

Dynamic List ADT. The program then performs the specified operations on the list and outputs the result

of each operation.

1.2.1 Linked List

l i n k e d l i s t

i n s e r t 0 10

i n s e r t 0 20

i n s e r t 1 30

g e t 0

g e t 1

g e t 2

d e l e t e 1

s i z e

d i s pl a y

Code Listing 1: Sample input file for creating a LinkedList

20

30

10

2

[ 2 0 , 1 0]

Code Listing 2: Sample output generated by the program

Page 2 of 9CS 201, Spring 2023 HW 2: Skiplists and Dynamic List ADT L5 – Group 3

1.2.2 Dynamic Array List

a r r a y

i n s e r t 0 10

d i s pl a y

i n s e r t 0 15

d i s pl a y

i n s e r t 1 5

d i s pl a y

s i z e

i n s e r t 2 30

d i s pl a y

d e l e t e 1

d i s pl a y

d e l e t e 1

d i s pl a y

s i z e

d e l e t e 1

d i s pl a y

Code Listing 3: Sample input file for creating a DynamicArrayList

[ 1 0 ]

[ 1 5 , 1 0]

[ 1 5 , 5 , 1 0 , ❂1]

3

[ 1 5 , 5 , 3 0 , 1 0]

[ 1 5 , 3 0 , 1 0 , ❂1]

[ 1 5 , 1 0 , ❂1, ❂1]

2

[ 1 5 , ❂1]

Code Listing 4: Sample output generated by the program

1.3 Testing

Once you have successfully implemented the DynamicArrayList and LinkedList classes, you can test your

code by reading from the accompanying data file, data/input.txt, and performing operations on the list

adt. For grading purposes, your submission will be tested automatically by GitHub using the accompanying

pytest file, test listadt.py.

Page 3 of 9CS 201, Spring 2023 HW 2: Skiplists and Dynamic List ADT L5 – Group 3

Part II

Skiplists

The solutions to the problems in this part are to be entered inline below. Remove all the other parts and

sections from this document. Enter your team name as the author in the document’s title.

  1. A Ranked Set

[10 points]

1 Design a version of a skiplist that implements the SSet interface, but also allows fast access to elements

by rank. That is, it also supports the function get(i), which returns the element whose rank is i in

O(log n) expected time. (The rank of an element x in an SSet is the number of elements in the SSet

that are less than x.) Describe how your version differs from a regular skiplist and provide pseudocode

of find(x) and get(i) for this version.

Solution:

To allow for faster access to elements by rank we can alter the regular skiplist such that it keeps track

of the size of the sublist rooted at each node. This will allow us to minimize the time complexity of

get() operation, which returns the element at a given index in the sorted set.

In this altered version we would include two additional pieces of information for each node:

size: the number of elements in each sublist starting at the node

rank: the rank of the node in the SSet, computed using the size

In a regular skiplist, to find the element at a given index, one would need to traverse the list from

the beginning until reaching the desired index. This would take O(n) time, where n is the number

of elements in the set. However, in this altered version of the skiplist, the size of each subtree is

stored at each node, so we can use this information to efficiently locate the element at the given

index.

To do this, we start at the sentinel node and traverse the skiplist, keeping track of the rank of

each node (the total number of elements visited so far, including the subtree sizes). When we reach

a node whose rank equals the desired index, we return its element. This takes O log(n) time on

average, where n is the number of elements in the set.

While this version of skiplist is similar to a regular skiplist in that it uses a linked list with multiple

levels of nodes to provide efficient search, insertion, and deletion operations, it differs in that it

maintains subtree sizes and uses them to efficiently support the get() operation.

The pseudocode of find(x) for this version is given below:

1

def find_pred_node (x):

2

u = sentinel

3

r = h

4

while r >= 0:

5

while u. next [r] is not None and u . next [r].x < x:

6

u = u . next [r]

# go right in

list r

7

r -= 1

# go down

into list r -1

8

return u

9

10

def find ( x):

11

u = find_pred_node ( x)

12

if u. next [0] is None :

13

return None

14

return u. next [0].x

1Adapted from Exercise 4.9 in the textbook.

Page 4 of 9CS 201, Spring 2023 HW 2: Skiplists and Dynamic List ADT L5 – Group 3

The pseudocode of get(i) for this version is given below:

1

def get (i ):

2

if i < 0 or i >= n:

3

raise IndexError ()

4

u = sentinel

5

r = h

6

rank = 0

7

while True :

8

while u. next [r] is not None and rank + u . next [r]. size <= i:

9

rank += u. next [r]. size

10

u = u. next [r]

11

if rank == i:

12

return u.x

13

r -= 1

In both the functions for the modified SSetSkipList, the average time complexity for both find(x)

and get(i) is O log(n).

Page 5 of 9CS 201, Spring 2023 HW 2: Skiplists and Dynamic List ADT L5 – Group 3

  1. Finger Search

[10 points]

2 A finger in a skiplist is an array that stores the sequence of nodes on a search path at which the search

path goes down. (The variable stack in the add(x) code on page 87 is a finger; the shaded nodes in

Figure 4.3 show the contents of the finger.) One can think of a finger as pointing out the path to a node

in the lowest list, L0.

A finger search implements the find(x) operation using a finger, walking up the list using the finger

until reaching a node u such that u.x < x and u.next = nil or u.next.x > x and then performing a

normal search for x starting from u. It is possible to prove that the expected number of steps required

for a finger search is O(1 + log r), where r is the number values in L0 between x and the value pointed

to by the finger.

Design, i.e. provide the necessary pseudo code for, a version of a skiplist that implements find(x)

operations using an internal finger. This subclass stores a finger, which is then used so that every

find(x) operation is implemented as a finger search. During each find(x) operation the finger is

updated so that each find(x) operation uses, as a starting point, a finger that points to the result of

the previous find(x) operation.

Solution:

To implement a skiplist that uses an internal finger for find(x) operations, we can store the finger

as an attribute of the skiplist. Whenever a find(x) operation is performed, we first use the finger

to perform a finger search and then update the finger to point to the node found by the search.

The find(x) method traverses the skip list from the highest level to the lowest level, moving the

current node pointer down to the next node in the list until it finds a node with a value greater

than or equal to the search value x. If it finds a node with a value equal to x, it returns True and

resets the finger to the head. Otherwise, it updates the finger to point to the last node before x and

returns False. This is done so we are able to use the finger for subsequent find(x) operations and

the only way we can guarantee that the finger points to a valid node is if it points to the node just

before x.

The pseudocode for this version of find(x) is given below:

1

class FingerSkipList :

2

initialize ():

3

head = fsl . Node ( None )

4

finger =

[ head ] * max_level

5

6

def find ( x):

7

i = finger [-1]

# start at the node pointed to by

the finger

8

for level in reversed ( range ( len (i. next ) )):

9

while i. next [ level ] and i. next [ level ]. val < x:

10

i = i . next [ level ]

11

if i . next [0] and i. next [0]. val == x:

12

finger =

[ head ] * max_level

# reset the finger

to the head

13

return True

14

finger =

[ None ] * len (i. next ) +

[i]

15

# update the finger

to point to the last node before x

16

return False

2Adapted from Exercise 4.10 in the textbook.

Page 6 of 9CS 201, Spring 2023 HW 2: Skiplists and Dynamic List ADT L5 – Group 3

Part III

Implementing a Database Index using a

Skiplist

Figure 1: An index over the Name attribute of a table. The index stores values of the Name attribute as

keys with the associated value being the address of the corresponding record in the table.

You have learned about database indexes in CS 355 Database Systems. Indexes in databases are similar

to indexes in books. In a book, an index allows you to find information quickly without reading the entire

book. In a database, an index allows the database program to find data in a table without scanning the

entire table. An index in a book is a sorted list of words with the page numbers that contain each word. An

index in a database is a sorted list of key values with the storage locations of rows in the table that contain

the key value. Each key in the index is associated with a particular pointer to a record in the data file.

Figure 1 shows an index on the Name attribute of an Instructor table stored in a data file. Note that key

values in the figure are not sorted.

The most popular data structure used for indexing in relational databases is Btree (or its variant, such

as B+tree). Btrees rose to popularity because they do fewer disk I/O operations to run a lookup compared

to other balanced trees. SingleStore is the first commercial relational database in production today to use a

skiplist, not a Btree, as its primary index data structure for in-memory data [1].

You are given a data file, data/books.csv, that contains records of books. Each record contains the

following attributes:

❼ Book Code

❼ Title

❼ Category

❼ Price

❼ Number of Pages

For some of the attributes, all the values are unique. Such attributes can be used to index the table. Others

have repeating values and are thus unsuitable to be used for indexing.

2 Implementation Details and Tasks

You are required to provide the missing implementations for the methods in the files, skiplist.py and

db.py, in the accompanying src/ sub-folder. skiplist.py contains classes to implement a skiplist. db.py

Page 7 of 9CS 201, Spring 2023 HW 2: Skiplists and Dynamic List ADT L5 – Group 3

contains a Table class to store records which can be indexed using a skiplist. Every individual field in the

Table is stored as strings. Further details are provided in the doc strings in the files. The methods to be

implemented are identified with a pass in their body.

2.1 Requirement

You will need to install the typing module to support certain type hints used in the code.

2.2 Tips

Below are some tips to avoid the errors that have previously caused tests to fail. Following these may save

you many frustrating hours of debugging!

❼ Store each field that is read from file as a str.

❼ Store a record as a list of field values.

❼ Store a table as a collection of records.

❼ Make sure that the Table can be re-indexed during run-time.

❼ Take care that the keys for the index are the values of the specified attribute. And that the value

associated with each key is not the corresponding record, but a means to locate the record in the table.

❼ For the select_range query, think of an approach better than submitting multiple select queries.

2.3 Testing

Once you have successfully implemented the methods, you can test your code by reading from the accompa

nying data file, data/books.csv, and performing queries on it. For grading purposes, your submission will

be tested automatically by GitHub using the accompanying pytest file, test index.py.

Page 8 of 9CS 201, Spring 2023 HW 2: Skiplists and Dynamic List ADT L5 – Group 3

References

[1] The Story Behind SingleStore’s Skiplist Indexes,

https://www.singlestore.com/blog/

what-is-skiplist-why-skiplist-index-for-memsql/, last accessed on 16 Feb 2022.

Page 9 of 9