class Node:
def __init__(self, data):
self.data = data
self.next = None
self.prev = None
class DoublyLinkedList:
def __init__(self):
self.head = None
self.tail = None
def append(self, data):
"""Add a new node to the end of the doubly linked list."""
new_node = Node(data)
if not self.head:
self.head = self.tail = new_node
return
self.tail.next = new_node
new_node.prev = self.tail
self.tail = new_node
def prepend(self, data):
"""Add a new node to the beginning of the doubly linked list."""
new_node = Node(data)
if not self.head:
self.head = self.tail = new_node
return
new_node.next = self.head
self.head.prev = new_node
self.head = new_node
def insert_at_position(self, data, position):
"""Insert a new node at the specified position."""
new_node = Node(data)
if position == 0:
self.prepend(data)
return
current = self.head
index = 0
while current and index < position - 1:
current = current.next
index += 1
if not current:
raise IndexError("Position out of bounds")
new_node.next = current.next
if current.next:
current.next.prev = new_node
current.next = new_node
new_node.prev = current
def delete(self, data):
"""Delete a node with the specified value."""
current = self.head
while current:
if current.data == data:
if current.prev:
current.prev.next = current.next
else:
self.head = current.next # If deleting the head
if current.next:
current.next.prev = current.prev
else:
self.tail = current.prev # If deleting the tail
return
current = current.next
def search(self, data):
"""Search for a node with the specified value and return its index."""
current = self.head
index = 0
while current:
if current.data == data:
return index
current = current.next
index += 1
return -1
def reverse(self):
"""Reverse the doubly linked list."""
current = self.head
while current:
current.prev, current.next = current.next, current.prev
current = current.prev
self.head, self.tail = self.tail, self.head
def display(self):
"""Display the doubly linked list as a sequence of nodes."""
nodes = []
current = self.head
while current:
nodes.append(str(current.data))
current = current.next
print(" <-> ".join(nodes))
def size(self):
"""Return the number of nodes in the doubly linked list."""
current = self.head
count = 0
while current:
count += 1
current = current.next
return count
def is_empty(self):
"""Check if the doubly linked list is empty."""
return self.head is None
def get_first(self):
"""Return the first node (head) of the list."""
if self.head:
return self.head.data
return None
def get_last(self):
"""Return the last node (tail) of the list."""
if self.tail:
return self.tail.data
return None
def remove_duplicates(self):
"""Remove duplicate values from the doubly linked list."""
current = self.head
seen = set()
while current:
if current.data in seen:
self.delete(current.data)
else:
seen.add(current.data)
current = current.next
def clear(self):
"""Clear the entire doubly linked list."""
self.head = self.tail = None
def get_node_at_index(self, index):
"""Return the node at a given index."""
current = self.head
current_index = 0
while current:
if current_index == index:
return current.data
current = current.next
current_index += 1
return None # Index out of range
def delete_at_index(self, index):
"""Delete a node at the given index."""
if index == 0:
if self.head:
self.head = self.head.next
if self.head:
self.head.prev = None
return
current = self.head
current_index = 0
while current and current.next:
if current_index == index - 1:
if current.next:
current.next = current.next.next
if current.next:
current.next.prev = current
return
current = current.next
current_index += 1
raise IndexError("Index out of bounds")
def to_list(self):
"""Convert the doubly linked list to a Python list."""
result = []
current = self.head
while current:
result.append(current.data)
current = current.next
return result
def sort(self):
"""Sort the doubly linked list."""
if not self.head or not self.head.next:
return
# Implementing merge sort or any sorting algorithm
self.head = self._merge_sort(self.head)
def _merge_sort(self, head):
"""Helper function for merge sort."""
if not head or not head.next:
return head
middle = self._get_middle(head)
next_to_middle = middle.next
middle.next = None
left = self._merge_sort(head)
right = self._merge_sort(next_to_middle)
sorted_list = self._merge(left, right)
return sorted_list
def _get_middle(self, head):
"""Find the middle node of the list."""
if not head:
return head
slow = head
fast = head
while fast.next and fast.next.next:
slow = slow.next
fast = fast.next.next
return slow
def _merge(self, left, right):
"""Merge two sorted doubly linked lists."""
if not left:
return right
if not right:
return left
if left.data <= right.data:
left.next = self._merge(left.next, right)
if left.next:
left.next.prev = left
return left
else:
right.next = self._merge(left, right.next)
if right.next:
right.next.prev = right
return right
# Example usage
dll = DoublyLinkedList()
dll.append(10)
dll.append(20)
dll.append(30)
dll.display() # Output: 10 <-> 20 <-> 30
dll.prepend(5)
dll.display() # Output: 5 <-> 10 <-> 20 <-> 30
dll.insert_at_position(15, 2)
dll.display() # Output: 5 <-> 10 <-> 15 <-> 20 <-> 30
dll.insert_at_position(35, 5)
dll.display() # Output: 5 <-> 10 <-> 15 <-> 20 <-> 30 <-> 35
dll.insert_at_position(0, 0)
dll.display() # Output: 0 <-> 5 <-> 10 <-> 15 <-> 20 <-> 30 <-> 35
# Reverse the doubly linked list
dll.reverse()
dll.display() # Output: 35 <-> 30 <-> 20 <-> 15 <-> 10 <-> 5 <-> 0
# Size of the list
print(f"Size: {dll.size()}") # Output: Size: 7
# Search for an element
print(f"Search 15: {dll.search(15)}") # Output: Search 15: 3
# Remove duplicates (if any)
dll.remove_duplicates()
# Clear the doubly linked list
dll.clear()
dll.display() # Output: (empty list)
# Add some nodes again
dll.append(100)
dll.append(200)
dll.append(300)
dll.display() # Output: 100 <-> 200 <-> 300
# Convert to Python list
print(f"List as Python list: {dll.to_list()}") # Output: List as Python list: [100, 200, 300]
# Delete at index 1
dll.delete_at_index(1)
dll.display() # Output: 100 <-> 300
# Sort the list
dll.sort()
dll.display() # Output: 100 <-> 300 (already sorted in this case)