1# Initialise the Node
2class Node:
3    def __init__(self, data):
4        self.item = data
5        self.next = None
6        self.prev = None
7# Class for doubly Linked List
8class doublyLinkedList:
9    def __init__(self):
10        self.start_node = None
11    # Insert Element to Empty list
12    def InsertToEmptyList(self, data):
13        if self.start_node is None:
14            new_node = Node(data)
15            self.start_node = new_node
16        else:
17            print("The list is empty")
18    # Insert element at the end
19    def InsertToEnd(self, data):
20        # Check if the list is empty
21        if self.start_node is None:
22            new_node = Node(data)
23            self.start_node = new_node
24            return
25        n = self.start_node
26        # Iterate till the next reaches NULL
27        while n.next is not None:
28            n = n.next
29        new_node = Node(data)
30        n.next = new_node
31        new_node.prev = n
32    # Delete the elements from the start
33    def DeleteAtStart(self):
34        if self.start_node is None:
35            print("The Linked list is empty, no element to delete")
36            return 
37        if self.start_node.next is None:
38            self.start_node = None
39            return
40        self.start_node = self.start_node.next
41        self.start_prev = None;
42    # Delete the elements from the end
43    def delete_at_end(self):
44        # Check if the List is empty
45        if self.start_node is None:
46            print("The Linked list is empty, no element to delete")
47            return 
48        if self.start_node.next is None:
49            self.start_node = None
50            return
51        n = self.start_node
52        while n.next is not None:
53            n = n.next
54        n.prev.next = None
55    # Traversing and Displaying each element of the list
56    def Display(self):
57        if self.start_node is None:
58            print("The list is empty")
59            return
60        else:
61            n = self.start_node
62            while n is not None:
63                print("Element is: ", n.item)
64                n = n.next
65        print("\n")
66# Create a new Doubly Linked List
67NewDoublyLinkedList = doublyLinkedList()
68# Insert the element to empty list
69NewDoublyLinkedList.InsertToEmptyList(10)
70# Insert the element at the end
71NewDoublyLinkedList.InsertToEnd(20)
72NewDoublyLinkedList.InsertToEnd(30)
73NewDoublyLinkedList.InsertToEnd(40)
74NewDoublyLinkedList.InsertToEnd(50)
75NewDoublyLinkedList.InsertToEnd(60)
76# Display Data
77NewDoublyLinkedList.Display()
78# Delete elements from start
79NewDoublyLinkedList.DeleteAtStart()
80# Delete elements from end
81NewDoublyLinkedList.DeleteAtStart()
82# Display Data
83NewDoublyLinkedList.Display()1class ListNode:
2    def __init__(self, value, prev=None, next=None):
3        self.prev = prev
4        self.value = value
5        self.next = next
6
7class DoublyLinkedList:
8    def __init__(self, node=None):
9        self.head = node
10        self.tail = node
11        self.length = 1 if node is not None else 0
12
13    def __len__(self):
14        return self.length
15   
16  	def add_to_head(self, value):
17        new_node = ListNode(value, None, None)
18        self.length += 1
19        if not self.head and not self.tail:
20            self.head = new_node
21            self.tail = new_node
22        else:
23            new_node.next = self.head
24            self.head.prev = new_node
25            self.head = new_node
26 
27    def remove_from_head(self):
28        value = self.head.value
29        self.delete(self.head)
30        return value
31
32    def add_to_tail(self, value):
33        new_node = ListNode(value, None, None)
34        self.length += 1
35        if not self.tail and not self.head:
36            self.tail = new_node
37            self.head = new_node
38        else:
39            new_node.prev = self.tail
40            self.tail.next = new_node
41            self.tail = new_node
42            
43
44    def remove_from_tail(self):
45        value = self.tail.value
46        self.delete(self.tail)
47        return value
48            
49    def move_to_front(self, node):
50        if node is self.head:
51            return
52        value = node.value
53        if node is self.tail:
54            self.remove_from_tail()
55        else:
56            node.delete()
57            self.length -= 1
58        self.add_to_head(value)
59        
60    def move_to_end(self, node):
61        if node is self.tail:
62            return
63        value = node.value
64        if node is self.head:
65            self.remove_from_head()
66            self.add_to_tail(value)
67        else:
68            node.delete()
69            self.length -= 1
70            self.add_to_tail(value)
71
72    def delete(self, node):
73        self.length -= 1
74        if not self.head and not self.tail:
75            return
76        if self.head == self.tail:
77            self.head = None
78            self.tail = None
79        elif self.head == node:
80            self.head = node.next
81            node.delete()
82        elif self.tail == node:
83            self.tail = node.prev
84            node.delete()
85        else:
86            node.delete()
87
88    def get_max(self):
89        if not self.head:
90            return None
91        max_val = self.head.value
92        current = self.head
93        while current:
94            if current.value > max_val:
95                max_val = current.value
96            current = current.next
97        return max_val