Dsa Assignement2
Dsa Assignement2
2. insert(2) Operation
Before insertion:
Current list: 5 → 10 → 23
After inserting 2:
Since 2 is smaller than all existing values, it will be inserted at the front.
Updated list: 2 → 5 → 10 → 23
The new node 2 will have its next pointing to 5 and prev set to None.
The front pointer will now reference the new node 2.
3. remove(8) Operation
Before removal:
Current list: 8 → 10 → 15 → 23
After attempting to remove 8:
Node 8 exists at the front.
It will be removed, and front will now point to 10.Updated list: 10 → 15 → 23
4. remove(23) Operation
Before removal:
Current list: 5 → 10 → 15 → 23
After removing 23:
Node 23 exists at the back.
It will be removed, and back will now point to 15.
Updated list: 5 → 10 → 15
The next pointer of node 15 will be set to None.
Return value: True.
5. is_present(21) Operation
Current list:
7 → 18 → 19 → 21 → 26
Checking for 21:
Traverse nodes in the order: 7, 18, 19, 21.
Node 21 is found.
Return value: True.
6. is_present(7) Operation
Current list:
7 → 18 → 19 → 21 → 26
Checking for 7:
The first node is 7.
Return value: True.
7. is_present(11) Operation
Current list:
7 → 18 → 19 → 21 → 26
Checking for 11:
Traverse nodes in the order: 7, 18, 19.
11 is not found in the list.
Return value: False.
8. is_present(30) Operation
Current list:
7 → 18 → 19 → 21 → 26
Checking for 30:
Traverse nodes in the order: 7, 18, 19, 21, 26.
30 is not found.
Return value: False.
def __init__(self):
# Initialize the front and back pointers of the list
self.front = None
self.back = None
self._length = 0
def __len__(self):
# Return the length of the list
return self._length
# If the list is empty, set both front and back to the new node
if self.front is None:
self.front = self.back = new_node
else:
current = self.front
previous = None
self._length += 1
if current is None:
return False # Node not found
if current.next:
current.next.prev = current.prev
else:
self.back = current.prev
self._length -= 1
return True
def __iter__(self):
curr = self.front
while curr:
yield curr.data
curr = curr.next
def __reversed__(self):
curr = self.back
while curr:
yield curr.data
curr = curr.prev
# Test insertions
print("Inserting values into the sorted list...")
sorted_list.insert(10)
sorted_list.insert(5)
sorted_list.insert(15)
sorted_list.insert(7)
sorted_list.insert(12)
# Test removals
print("\nRemoving values from the list...")
print(f"Removing 10: {sorted_list.remove(10)}")
print(f"Removing 3 (not in list): {sorted_list.remove(3)}")
print(f"Removing 5: {sorted_list.remove(5)}")
3. is_present(data) Method
Singly Linked List Analysis
If we come across a node with a value higher than the data we're looking for, we can
end the search early because the list has been sorted.
The worst-case situation is that the value either doesn't exist or is greater than any
value in the list.
Time Complexity:
O(n) in the worst case (i.e., when we have to traverse all nodes).