Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
191 changes: 191 additions & 0 deletions Answers/LinkedList.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
class Node:
def __init__(self, data):
self.data = data
self.next = None


class LinkedList:
def __init__(self):
self.head = None

# insert in back
def append(self, data):
newNode = Node(data)
if not self.head:
self.head = newNode
return
lastNode = self.head
while lastNode.next:
lastNode = lastNode.next
lastNode.next = newNode

# insert in front
def prepend(self, data):
newNode = Node(data)
newNode.next = self.head
self.head = newNode

def insert_after(self, prev_node_data, data):
if not self.head:
print("The linked list is empty.")
return
currentNode = self.head
while currentNode:
if currentNode.data == prev_node_data:
new_node = Node(data)
new_node.next = currentNode.next
currentNode.next = new_node
return
currentNode = currentNode.next
print(f"{prev_node_data} not found in the linked list.")

def delete(self, data):
if not self.head:
print("The linked list is empty.")
return
if self.head.data == data:
self.head = self.head.next
return
prevNode = self.head
currentNode = self.head.next
while currentNode:
if currentNode.data == data:
prevNode.next = currentNode.next
return
prevNode = currentNode
currentNode = currentNode.next
print(f"{data} not found in the linked list.")

def display(self):
if not self.head:
print("The linked list is empty.")
return
currentNode = self.head
while currentNode:
print(currentNode.data, end=" -> ")
currentNode = currentNode.next
print("None")

def delete_at_front(self):
if self.head == None:
print("LinkedList is empty")

else:
deletedValue = self.head.data
self.head = self.head.next
print(deletedValue)

def delete_at_back(self):
if self.head == None:
print('LinkedList is empty')

# If there is only one node
if self.head.next == None:
deletedValue = self.head.data
self.head = None
print(deletedValue)
lastElement = self.head
while lastElement.next.next:
prevLastElement = lastElement
lastElement = lastElement.next
deletedValue = lastElement.next.data
lastElement.next = None
print(deletedValue)

def search(self, value):
if self.head == None:
print("LinkedList is empty")
current = self.head
position = 0
while current:
if current.data == value:
print(f"list.search({value}) -> {position}")
current = current.next
position += 1
print("nothing found")

def clear(self):
if self.head == None:
print("LinkedList is empty")
self.head = None
print("LinkedList cleared")

def size(self):
if self.head == None:
print("LinkedList is empty")
current = self.head
count = 0
while current:
count += 1
current = current.next
print(f"LinkedListSize()-> ({count})")

def print_forward(self):
if self.head == None:
print("LinkedList is empty")
return
current = self.head
while current:
print(current.data, end=" ")
current = current.next
print()

def print_backward(self):
if self.head == None:
print("LinkedList is empty")
return
self._print_backward_recursive(self.head)
print()

def _print_backward_recursive(self, node):
if node.next:
self._print_backward_recursive(node.next)
print(node.data, end=" ")

def reverse_recursive(self):
if self.head == None:
print("LinkedList is empty")
return
self.head = self._reverse_recursively(self.head)

def _reverse_recursively(self, current):
if current.next == None:
return current
new_head = self._reverse_recursively(current.next)
current.next.next = current
current.next = None
return new_head

def reverse_non_recursively(self):
if self.head == None:
print("LinkedList is empty")
return
prevNode = None
currentNode = self.head
while currentNode:
nextNode = currentNode.next
currentNode.next = prevNode
prevNode = currentNode
currentNode = nextNode
self.head = prevNode


# Example usage
ll = LinkedList()
ll.append(1)
ll.append(2)
ll.append(3)
ll.append(25)
ll.prepend(10)
ll.display()
ll.delete_at_front()

ll.delete_at_back()

ll.search(10)
ll.size()
ll.print_forward()
ll.reverse_non_recursively()
ll.display()
ll.clear()
ll.display()
180 changes: 180 additions & 0 deletions Answers/LinkedListDoubly.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
class DoublyNode:
def __init__(self, data):
self.data = data
self.next = None
self.prev = None


class DoublyLinkedList:
def __init__(self):
self.head = None

def append(self, data):
newNode = DoublyNode(data)
if not self.head:
self.head = newNode
return
lastNode = self.head
while lastNode.next:
lastNode = lastNode.next
lastNode.next = newNode
newNode.prev = lastNode

# insert in front
def prepend(self, data):
newNode = DoublyNode(data)
if self.head:
self.head.prev = newNode
newNode.next = self.head
self.head = newNode

def display(self):
if not self.head:
print("The linked list is empty.")
return
current_node = self.head
while current_node:
print(current_node.data, end=" <-> ")
current_node = current_node.next
print("None")

def delete_at_front(self):
if not self.head:
print("LinkedList is empty")
return
deletedValue = self.head.data
self.head = self.head.next
if self.head:
self.head.prev = None
print(deletedValue)

def delete_at_back(self):
if not self.head:
print('LinkedList is empty')
return
if self.head.next is None:
deletedValue = self.head.data
self.head = None
print(deletedValue)
return
lastNode = self.head
while lastNode.next:
lastNode = lastNode.next
deletedValue = lastNode.data
lastNode.prev.next = None
print(deletedValue)

def search(self, value):
if not self.head:
print("LinkedList is empty")
return
current = self.head
position = 0
while current:
if current.data == value:
print(f"list.search({value}) -> {position}")
return
current = current.next
position += 1
print("nothing found")

def clear(self):
self.head = None
print("LinkedList cleared")

def size(self):
if not self.head:
print("LinkedList is empty")
return
current = self.head
count = 0
while current:
count += 1
current = current.next
print(f"LinkedListSize() -> {count}")

def print_forward(self):
if not self.head:
print("LinkedList is empty")
return
current = self.head
while current:
print(current.data, end=" ")
current = current.next
print()

def print_backward(self):
if not self.head:
print("LinkedList is empty")
return
current = self.head
while current.next:
current = current.next
while current:
print(current.data, end=" ")
current = current.prev
print()

def reverse_non_recursively(self):
if not self.head:
print("LinkedList is empty")
return
current = self.head
prev = None
while current:
next_node = current.next
current.next = prev
current.prev = next_node
prev = current
current = next_node
self.head = prev

def shift(self, num):
if not self.head:
print("LinkedList is empty")
return
if num == 0:
return
current = self.head
length = 1
while current.next:
current = current.next
length += 1
current.next = self.head
self.head.prev = current
num %= length
for _ in range(length - num):
self.head = self.head.next
current = self.head.prev
current.next = None
self.head.prev = None


# make the singleLinkedList to doublyLinkedList
def make_doubly(singly_linked_list):
doubly_linked_list = DoublyLinkedList()
current = singly_linked_list.head
while current:
doubly_linked_list.append(current.data)
current = current.next
return doubly_linked_list


# Example usage
dll = DoublyLinkedList()
dll.append(1)
dll.append(2)
dll.append(3)
dll.append(10)
dll.prepend(25)
dll.display()
dll.delete_at_front()
dll.delete_at_back()
dll.search(10)
dll.size()
dll.print_forward()
dll.print_backward()
dll.reverse_non_recursively()
dll.display()
dll.clear()
dll.display()