Design a Doubly Linked List
Design a doubly linked list (DLL) with the following operations:
- insert_at_head(val): Insert a node with the given value at the beginning of the doubly linked list.
- insert_at_tail(val): Insert a node with the given value at the end of the doubly linked list.
- insert_after_node(node, val): Insert a node with the given value after the specified node in the doubly linked list.
- delete_at_head(): Delete the node at the beginning of the doubly linked list.
- delete_at_tail(): Delete the node at the end of the doubly linked list.
- delete_node(node): Delete the specified node from the doubly linked list.
- display(): Display the elements of the doubly linked list.
The doubly linked list should have the following structure:
class ListNode:
    def __init__(self, val=0, prev=None, next=None):
        self.val = val
        self.prev = prev
        self.next = next
Example:
dll = DoublyLinkedList()
dll.insert_at_head(1)
dll.insert_at_tail(2)
dll.insert_at_tail(3)
dll.insert_after_node(dll.head.next, 4)
dll.display()  # Output: 1 <-> 2 <-> 4 <-> 3
dll.delete_at_head()
dll.display()  # Output: 2 <-> 4 <-> 3
dll.delete_at_tail()
dll.display()  # Output: 2 <-> 4
dll.delete_node(dll.head.next)
dll.display()  # Output: 2
Note:
- Assume that the input parameters are valid for all operations.
Instructions:
- Write the DoublyLinkedListclass with the specified operations.
- Implement your solution in Python.
- Provide clear comments in your code.
- Demonstrate the usage of your doubly linked list with a simple example.
As always, we’ll share our solution to this problem tomorrow. Stay tuned 😊