In: Computer Science
Python class DLLNode: """ Class representing a node in the doubly linked list implemented below. """ def __init__(self, value, next=None, prev=None): """ Constructor @attribute value: the value to give this node @attribute next: the next node for this node @attribute prev: the previous node for this node """ self.__next = next self.__prev = prev self.__value = value def __repr__(self): return str(self.__value) def __str__(self): return str(self.__value) def get_value(self): """ Getter for value :return: the value of the node """ return self.__value def set_value(self, value): """ Setter for value :param value: the value to set """ self.__value = value def get_next(self): """ Getter for next node :return: the next node """ return self.__next def set_next(self, node): """ Setter for next node :param node: the node to set """ self.__next = node def get_previous(self): """ Getter for previous node :return: the previous node """ return self.__prev def set_previous(self, node): """ Setter for previous node :param node: the node to set """ self.__prev = node class DLL: """ Class representing a doubly linked list. """ def __init__(self): """ Constructor @attribute head: the head of the linked list @attribute tail: the tail of the linked list @attribute size: the size of the linked list """ self.head = None self.tail = None self.size = 0 def __repr__(self): """ iterates through the linked list to generate a string representation :return: string representation of the linked list """ res = "" node = self.head while node: res += str(node) if node.get_next(): res += " " node = node.get_next() return res def __str__(self): """ iterates through the linked list to generate a string representation :return: string representation of the linked list """ res = "" node = self.head while node: res += str(node) if node.get_next(): res += " " node = node.get_next() return res ######### MODIFY BELOW ########## def get_size(self): """ Gives the user the size of their linked list :return: [int] the size of the linked list """ def is_empty(self): """ Determines if the linked list is empty or not :return: [boolean] true if DLL is empty, false otherwise """ def insert_front(self, value): """ Inserts a value into the front of the list :param value: the value to insert """ def insert_back(self, value): """ Inserts a value into the back of the list :param value: the value to insert """ def delete_front(self): """ Deletes the front node of the list """ def delete_back(self): """ Deletes the back node of the list """ def delete_value(self, value): """ Deletes the first instance of the value in the list. :param value: The value to remove """ def delete_all(self, value): """ Deletes all instances of the value in the list :param value: the value to remove """ pass def find_first(self, value): """ Finds the first instance of the value in the list :param value: the value to find :return: [DLLNode] the first node containing the value """ pass def find_last(self, value): """ Finds the last instance of the value in the list :param value: the value to find :return: [DLLNode] the last node containing the value """ pass def find_all(self, value): """ Finds all of the instances of the value in the list :param value: the value to find :return: [List] a list of the nodes containing the value """ pass def count(self, value): """ Finds the count of times that the value occurs in the list :param value: the value to count :return: [int] the count of nodes that contain the given value """ pass def sum(self): """ Finds the sum of all nodes in the list :param start: the indicator of the contents of the list :return: the sum of all items in the list """ pass def remove_middle(LL): """ Removes the middle of a given doubly linked list. :param DLL: The doubly linked list that must be modified :return: The updated linked list """ pass
This is the testcases
import unittest from DLL import DLL, DLLNode, remove_middle class TestProject1(unittest.TestCase): def test_inserts(self): lst = DLL() lst.insert_front(1) lst.insert_front(2) lst.insert_front(3) lst.insert_back(4) lst.insert_back(5) self.assertEqual(lst.head.get_value(), 3) self.assertEqual(lst.tail.get_value(), 5) forward, backward = [], [] head = lst.head while head is not None: forward.append(head.get_value()) head = head.get_next() tail = lst.tail while tail is not None: backward.append(tail.get_value()) tail = tail.get_previous() self.assertEqual(forward, [3, 2, 1, 4, 5]) self.assertEqual(backward, [5, 4, 1, 2, 3]) def test_accessors(self): lst = DLL() self.assertTrue(lst.is_empty()) self.assertEqual(lst.get_size(), 0) for _ in range(5): lst.insert_front(1) self.assertTrue(not lst.is_empty()) self.assertEqual(lst.get_size(), 5) for _ in range(3): lst.delete_front() self.assertTrue(not lst.is_empty()) self.assertEqual(lst.get_size(), 2) def test_deletes(self): def condense(linkedlist): res = list() node = linkedlist.head while node is not None: res.append(node.get_value()) node = node.get_next() return res lst = DLL() inserts = [1, 4, 0, 10, 3, 7, 9] for x in inserts: lst.insert_back(x) lst.delete_front() inserts.pop(0) self.assertEqual(inserts, condense(lst)) lst.delete_back() inserts.pop() self.assertEqual(inserts, condense(lst)) def test_delete_value_all(self): def condense(linkedlist): res = list() node = linkedlist.head while node is not None: res.append(node.get_value()) node = node.get_next() return res lst = DLL() insert = [1, 2, 3, 4, 5, 6, 1, 1, 2, 4, 1, 9] for i in insert: lst.insert_back(i) lst.delete_value(1) self.assertEqual(condense(lst), insert[1:]) lst.delete_all(1) self.assertEqual(condense(lst), [2, 3, 4, 5, 6, 2, 4, 9]) def test_finds(self): lst = DLL() inserts = [9, 16, 5, 58, 32, 1, 4, 58, 67, 2, 4] for i in inserts: lst.insert_back(i) first = lst.find_first(32) self.assertEqual(first.get_value(), 32) self.assertEqual(first.get_next().get_value(), 1) self.assertEqual(first.get_previous().get_value(), 58) last = lst.find_last(2) self.assertEqual(last.get_value(), 2) self.assertEqual(last.get_next().get_value(), 4) self.assertEqual(last.get_previous().get_value(), 67) list_of_58s = lst.find_all(58) self.assertEqual(len(list_of_58s), 2) for i in list_of_58s: self.assertEqual(i.get_value(), 58) first = list_of_58s[0] second = list_of_58s[1] self.assertEqual(first.get_next().get_value(), 32) self.assertEqual(first.get_previous().get_value(), 5) self.assertEqual(second.get_next().get_value(), 67) self.assertEqual(second.get_previous().get_value(), 4) def test_count_sum(self): lst = DLL() inserts = [1, 3, 1, 4, 5, 6, 1, 3, 8] for i in inserts: lst.insert_back(i) self.assertEqual(lst.count(1), 3) self.assertEqual(lst.sum(), 32) def test_remove_middle(self): def condense(linkedlist): res = list() node = linkedlist.head while node is not None: res.append(node.get_value()) node = node.get_next() return res lst = DLL() inserts = [1, 2, 3, 4, 5] for i in inserts: lst.insert_back(i) new = remove_middle(lst) self.assertEqual(condense(new), [1, 2, 4, 5]) if __name__ == "__main__": unittest.main()
Thanks a lot!
Code:
class DLLNode:
"""
Class representing a node in the doubly linked list implemented
below.
"""
def __init__(self, value, next=None, prev=None):
"""
Constructor
@attribute value: the value to give this node
@attribute next: the next node for this node
@attribute prev: the previous node for this node
"""
self.__next = next
self.__prev = prev
self.__value = value
def __repr__(self):
return str(self.__value)
def __str__(self):
return str(self.__value)
def get_value(self):
"""
Getter for value
:return: the value of the node
"""
return self.__value
def set_value(self, value):
"""
Setter for value
:param value: the value to set
"""
self.__value = value
def get_next(self):
"""
Getter for next node
:return: the next node
"""
return self.__next
def set_next(self, node):
"""
Setter for next node
:param node: the node to set
"""
self.__next = node
def get_previous(self):
"""
Getter for previous node
:return: the previous node
"""
return self.__prev
def set_previous(self, node):
"""
Setter for previous node
:param node: the node to set
"""
self.__prev = node
class DLL:
"""
Class representing a doubly linked list.
"""
def __init__(self):
"""
Constructor
@attribute head: the head of the linked list
@attribute tail: the tail of the linked list
@attribute size: the size of the linked list
"""
self.head = None
self.tail = None
self.size = 0
def __repr__(self):
"""
iterates through the linked list to generate a string
representation
:return: string representation of the linked list
"""
res = ""
node = self.head
while node:
res += str(node)
if node.get_next():
res += " "
node = node.get_next()
return res
def __str__(self):
"""
iterates through the linked list to generate a string
representation
:return: string representation of the linked list
"""
res = ""
node = self.head
while node:
res += str(node)
if node.get_next():
res += " "
node = node.get_next()
return res
def get_size(self):
#returns the size of linked list
return self.size
def is_empty(self):
#if size is 0 then linked list is empty else no
return True if(self.get_size()==0) else False
def insert_front(self, value):
#If linked list empty then we need to update both head and tail pointers
#else only update head pointer
#increase the size by 1
newNode=DLLNode(value)
if(self.get_size()==0):
self.head=newNode
self.tail=newNode
self.size=1
else:
newNode.set_next(self.head)
self.head.set_previous(newNode)
self.head=newNode
self.size+=1
def insert_back(self, value):
#if list is empty then update both head and tail
#else update only tail
#increase size by 1
newNode=DLLNode(value)
if(self.get_size()==0):
self.head=newNode
self.tail=newNode
self.size=1
else:
newNode.set_previous(self.tail)
self.tail.set_next(newNode)
self.tail=newNode
self.size+=1
def delete_front(self):
#if list is empty then there is nothing to delete
#if only 1 element exist then make head and tail None
#else move the head pointer to head.next
#decrease size by 1
if(self.get_size()==0):
print("Sry! linkedlist is empty. Can't delete the element")
return
if(self.get_size()==1):
self.head=None
self.tail=None
self.size=0
else:
self.head=self.head.get_next();
self.head.set_previous(None)
self.size-=1
def delete_back(self):
#if list is empty then there is nothing to delete
#if only 1 element exist then make head and tail None
#else move tail pointer to tail.previous
#decrement size by 1
if(self.get_size()==0):
print("Sry! linkedlist is empty. Can't delete the element")
return
if(self.get_size()==1):
self.head=None
self.tail=None
self.size=0
else:
self.tail=self.tail.get_previous()
self.tail.set_next(None)
self.size-=1
def delete_value(self, value):
#check if 1st element is value if true then call delete_front() method
#else find the node that contains value
#if value is not present then node will point to None so nothing to delete
#elseif check node is same as tail if so call delete_back() method
#else delete the current node
if(self.get_size()==0): return
if(self.head.get_value()==value):
self.delete_front()
return
node=self.head
while(node):
if(node.get_value()==value):
break
node=node.get_next()
if(node):
if(node.get_next()==None):#value is the last element
self.delete_back()
return
temp=node
node=node.get_previous()
node.set_next(temp.get_next())
temp=temp.get_next()
temp.set_previous(node)
self.size-=1
def delete_all(self, value):
#get the current size of list then call delete_value() method
#now check whether present size is same as previous size or not
#run while loop until size of list is same before calling delete_value() method and after this method
val=self.get_size()
self.delete_value(value)
while(val!=self.get_size()):
val=self.get_size()
self.delete_value(value)
def find_first(self, value):
#Traverse from head pointer and traverse forward until we found the first instance of value
#if nothing found then return None
node=self.head
while(node):
if(node.get_value()==value):
return node
node=node.get_next()
return None
def find_last(self, value):
#traverse from tail pointer in backwards and find 1st instance and return
#if nothing found return None
node=self.tail
while(node):
if(node.get_value()==value):
return node
node=node.get_previous()
return None
def find_all(self, value):
#traverse from head pointer in forward direction
#store the nodes if node.value==value and return the list after all traversals
node=self.head
ans=[]
while(node):
if(node.get_value()==value):
ans.append(node)
node=node.get_next()
return ans
def count(self, value):
#u can simply use return len(find_all(value))
count=0
node=self.head
while(node):
if(node.get_value()==value):
count+=1
node=node.get_next()
return count
def sum(self):
total=0
node=self.head
while(node):
total+=node.get_value()
node=node.get_next()
return total
def remove_middle(LL):
#if size if odd I am removing (n+1)/2th element (1 2 3 4 5 -> 1 2 4 5)
#else n/2th element (1 2 3 4 -> 1 3 4)
if(LL.get_size()==0): return LL
if(LL.get_size()<3):
#if only 1 element then make list empty else remove 1st element
LL.delete_front()
return LL
slow=LL.head
fast=LL.head
while(fast and fast.get_next()):
fast=fast.get_next()
if(fast and fast.get_next()):
fast=fast.get_next()
slow=slow.get_next()
fast=slow.get_previous()
slow=slow.get_next()
fast.set_next(slow)
slow.set_previous(fast)
LL.size-=1
return LL
The output of the file after runnig testProject1 file is:
.......
----------------------------------------------------------------------
Ran 7 tests in 0.002s
OK
If you have any queries feel free to ask. Thank you