I'm following a tutorial on merging two bubble-sorted Single Linked Lists in Python.
merge1
creates a new list and does the merging.
Other than naming conventions which are not the best and I'm just following the tutorial, any feedback would be appreciated. OOP, practical time-complexity, algorithms, and others.
class Node:
# Instantiates the node class
def __init__(self, value):
self.info = value
self.link = None
class SingleLinkedList:
# Instantiates the single linked list class
def __init__(self):
self.start = None
# Creates the single linked list
def create_list(self):
n = int(input("Enter the number of nodes in the list you wish to create: "))
if n == 0:
return
for i in range(n):
data = int(input("Enter the element to be inserted: "))
self.insert_at_end(data)
# Counts the nodes of the single linked list
def count_nodes(self):
p = self.start
n = 0
while p is not None:
n += 1
p = p.link
print("💚 The number of nodes in single linked list is: " + str(n))
# Searches the x integer in the linked list
def search(self, x):
position = 1
p = self.start
while p is not None:
if p.info == x:
print("💚 YAAAY! We found " + str(x) + " at position " + str(position))
return True
# Increment the position
position += 1
# Assign the next node to the current node
p = p.link
else:
print("💔 Sorry! We couldn't find " + str(x) + " at any position. Maybe, try again later!")
return False
# Displays the list
def display_list(self):
if self.start is None:
print("💛 Single linked list is empty!")
return
else:
print("💚 Single linked list includes: ")
p = self.start
while p is not None:
print(p.info, " ", end=' ')
p = p.link
print()
# Inserts an integer in the beginning of the linked list
def insert_in_beginning(self, data):
temp = Node(data)
temp.link = self.start
self.start = temp
# Inserts an integer at the end of the linked list
def insert_at_end(self, data):
temp = Node(data)
if self.start is None:
self.start = temp
return
p = self.start
while p.link is not None:
p = p.link
p.link = temp
# Inserts an integer after the x node
def insert_after(self, data, x):
p = self.start
while p is not None:
if p.info == x:
break
p = p.link
if p is None:
print("💔 Sorry! " + str(x) + " is not in the list.")
else:
temp = Node(data)
temp.link = p.link
p.link = temp
# Inserts an integer before the x node
def insert_before(self, data, x):
# If list is empty
if self.start is None:
print("💔 Sorry! The list is empty.")
return
# If x is the first node, and new node should be inserted before the first node
if x == self.start.info:
temp = Node(data)
temp.link = p.link
p.link = temp
# Finding the reference to the prior node containing x
p = self.start
while p.link is not None:
if p.link.info == x:
break
p = p.link
if p.link is not None:
print("💔 Sorry! " + str(x) + " is not in the list.")
else:
temp = Node(data)
temp.link = p.link
p.link = temp
# Inserts an integer in k position of the linked list
def insert_at_position(self, data, k):
# if we wish to insert at the first node
if k == 1:
temp = Node(data)
temp.link = self.start
self.start = temp
return
p = self.start
i = 1
while i < k-1 and p is not None:
p = p.link
i += 1
if p is None:
print("💛 The max position is: " + i)
else:
temp = Node(data)
temp.link = self.start
self.start = temp
# Deletes a node of a linked list
def delete_node(self, x):
# If list is empty
if self.start is None:
print("💔 Sorry! The list is empty.")
return
# If there is only one node
if self.start.info == x:
self.start = self.start.link
# If more than one node exists
p = self.start
while p.link is not None:
if p.link.info == x:
break
p = p.link
if p.link is None:
print("💔 Sorry! " + str(x) + " is not in the list.")
else:
p.link = p.link.link
# Deletes the first node of a linked list
def delete_first_node(self):
if self.start is None:
return
self.start = self.start.link
# Deletes the last node of a linked list
def delete_last_node(self):
# If the list is empty
if self.start is None:
return
# If there is only one node
if self.start.link is None:
self.start = None
return
# If there is more than one node
p = self.start
# Increment until we find the node prior to the last node
while p.link.link is not None:
p = p.link
p.link = None
# Reverses the linked list
def reverse_list(self):
prev = None
p = self.start
while p is not None:
next = p.link
p.link = prev
prev = p
p = next
self.start = prev
# Bubble sorts the linked list with respect to data
def bubble_sort_exdata(self):
# If the list is empty or there is only one node
if self.start is None or self.start.link is None:
print("💛 The list has no or only one node and sorting is not required.")
end = None
while end != self.start.link:
p = self.start
while p.link != end:
q = p.link
if p.info > q.info:
p.info, q.info = q.info, p.info
p = p.link
end = p
# Bubble sorts the linked list with respect to links
def bubble_sort_exlinks(self):
# If the list is empty or there is only one node
if self.start is None or self.start.link is None:
print("💛 The list has no or only one node and sorting is not required.")
end = None
while end != self.start.link:
r = p = self.start
while p.link != end:
q = p.link
if p.info > q.info:
p.link = q.link
q.link = p
if p != self.start:
r.link = q.link
else:
self.start = q
p, q = q, p
r = p
p = p.link
end = p
#Merges two already sorted single linked lists by creating new lists
def merge1(self, list2):
merge_list = SingleLinkedList()
merge_list.start = self._merge1(self.start, list2.start)
return merge_list
def _merge1(self, p1, p2):
if p1.info <= p2.info:
StartM = Node(p1.info)
p1 = p1.link
else:
StartM = Node(p2.info)
p2 = p2.link
pM = StartM
while p1 is not None and p2 is not None:
if p1.info <= p2.info:
pM.link = Node(p1.info)
p1 = p1.link
else:
pM.link = Node(p2.info)
p2 = p2.link
pM = pM.link
# If the second list is finished, yet the first list has some nodes
while p1 is not None:
pM.link = Node(p1.info)
p1 = p1.link
pM = pM.link
# If the second list is finished, yet the first list has some nodes
while p2 is not None:
pM.link = Node(p2.info)
p2 = p2.link
pM = pM.link
return StartM
# Testing
list1 = SingleLinkedList()
list2 = SingleLinkedList()
list1.create_list()
list2.create_list()
list1.bubble_sort_exdata()
list2.bubble_sort_exdata()
print("1️⃣ The first list is: ")
list1.display_list()
print("2️⃣ The second list is: ")
list2.display_list()
list3 = list1.merge1(list2)
print("The merged list by creating a new list is: ")
list3.display_list()
Output
1️⃣ The first list is:
💚 Single linked list includes:
1 1 1 2 3
2️⃣ The second list is:
💚 Single linked list includes:
1 3 6 6
The merged list by creating a new list is:
💚 Single linked list includes:
1 1 1 1 2 3 3 6 6