I've recently learned how to implement linked list in Python. Can anyone help me to refine my code of implementing methods 'insert()', and 'pop()'.
pop(pos) - remove and return item at position pos.
insert(pos, item) - adds a new item to the list at position pos.
Did I consider all the cases? Thank you in advance!
EDITED: I've add test cases for pop
and insert
class Node: def __init__(self, data): '''create a node''' self.data = data self.next = None # LINKED LIST IMPLEMENTATION class LinkedList: def __init__(self): self.head = None def isEmpty(self): return self.head == None def __repr__(self): '''ll representation O(n)''' nodes = [] cur = self.head while cur: nodes.append(str(cur.data)) cur = cur.next nodes.append("None") return '->'.join(nodes) def add(self, item): '''add a new item at the head of ll O(1)''' # create a new node for item newNode = Node(item) # set newnode to refer to head newNode.next = self.head # set newnode to be new head self.head = newNode def size(self): '''return #nodes O(n)''' # traverse ll and count nodes cur = self.head count = 0 while cur != None: count += 1 cur = cur.next return count def search(self, key): '''search for key in ll''' # traverse ll to find key # O(n) cur = self.head while cur: if cur.data == key: return True cur = cur.next return False def remove(self, key): '''remove key from ll O(n)''' # if ll empty, raise error if self.head == None: raise Exception("Linked list is empty!") # if head holds key, set a new head if self.head.data == key: self.head = self.head.next return # otherwise, traverse ll for key prev = None cur = self.head while cur: # key found if cur.data == key: prev.next = cur.next return # key not found yet, move prev and cur 1 node ahead prev = cur cur = cur.next # cur is None, key not present raise Exception('Key not present in ll!') def append(self, item): '''append an item to the end of ll. O(n)''' # create a new node for item, by default node points to None newNode = Node(item) # if ll is empty, set head to be new node if self.head == None: self.head = newNode return # otherwise, traverse the whole ll cur = self.head while cur.next: cur = cur.next cur.next = newNode def index(self, key): '''return idnex of key in ll O(n)''' # if ll empty, raise error if self.head == None: raise Exception("LL is empty!") # traverse ll to find key pos = 0 cur = self.head while cur: if cur.data == key: return pos # found # else, move to next node cur = cur.next pos += 1 # key not present return -1 def popLastNode(self): '''remove and return last item of ll. O(n)''' # if ll is empty, cant pop if self.head == None: raise Exception('ll is empty!') # only 1 node, set ll to empty if self.head.next == None: self.head = None return # otherwise, traverse ll and remove last node cur = self.head while cur.next.next: cur = cur.next lastVal = cur.next.data cur.next = None return lastVal def pop(self, pos=0): '''remove and return item at pos O(n)''' # invalid pos if pos < 0 or pos >= self.size(): raise IndexError('Index out of range!') # otherwise, traverse ll to pos prev = None cur = self.head idx = 0 # index of cur node while idx < pos: prev, cur = cur, cur.next # pop at the beginning if idx == 0: val = self.head.data self.head = self.head.next return val val = cur.data prev.next = cur.next return val def insert(self, item, pos=0): '''insert an item at pos. invalid pos > error pos == 0, change head''' # create a new node for item newNode = Node(item) # pos == 0, set new head (add method) if pos == 0: newNode.next = self.head self.head = newNode return # invalid pos if pos < 0 or pos >= self.size(): raise IndexError('Index out of range!') # otherwise, traverse ll prev = None cur = self.head # insert between prev and cur idx = 0 while idx < pos: prev = cur cur = cur.next idx += 1 prev.next = newNode newNode.next = cur # TEST CASES # pop method l5 = LinkedList() # l5.pop(-1) - error, index out of range # l5.pop(0) - error, index out of range # l5.pop(5) - error, index out range l5.add(1) print(l5.pop()) # 1 l5.add(2) l5.add(3) l5.add(4) print(l5) # print(l5.pop(4)) - error, idx out of range print(l5.pop(2)) print(l5) #%% # insert l6 = LinkedList() # l6.insert(2, 1) - error, index out of range l6.insert(2) print(l6) # l6.insert(3, 2) - error, index out of range # l6.insert(3, 1) - error, index out of range l6.insert(3) l6.insert(4, 1) print(l6) l6.insert(5, 1) print(l6)