Starting from:

$30

CS201 Homework 2 -Solved


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 structure⟩ is either array or linkedlist, indicating which data structure should be used to 
implement the Dynamic List ADT 
❼ ⟨ operation⟩ is one of the following: 
– insert: Insert an item into the list. The ⟨arg1⟩ is the index at which to insert the item and ⟨arg2⟩ 
is the item to be inserted. 
– delete: Delete an item from the list. The ⟨arg1⟩ is the index of the item to be deleted. 
– get: Return the item at the specified index in the list. The ⟨arg1⟩ is 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 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] 

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

[ 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: 

def find_pred_node (x): 

u = sentinel 

r = h 

while r >= 0: 

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

u = u . next [r] 
# go right in 
list r 

r -= 1 
# go down 
into list r -1 

return u 

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: 

def get (i ): 

if i < 0 or i >= n: 

raise IndexError () 

u = sentinel 

r = h 

rank = 0 

while True : 

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

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 
2. 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: 

class FingerSkipList : 

initialize (): 

head = fsl . Node ( None ) 

finger = 
[ head ] * max_level 
5

def find ( x): 

i = finger [-1] 
# start at the node pointed to by 
the finger 

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

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

More products