| 
 | 1 | +"""Each ListNode holds a reference to its previous node  | 
 | 2 | +as well as its next node in the List."""  | 
 | 3 | + | 
 | 4 | + | 
 | 5 | +class ListNode:  | 
 | 6 | +    def __init__(self, value, prev=None, next=None):  | 
 | 7 | +        self.value = value  | 
 | 8 | +        self.prev = prev  | 
 | 9 | +        self.next = next  | 
 | 10 | + | 
 | 11 | +    """Wrap the given value in a ListNode and insert it  | 
 | 12 | +    after this node. Note that this node could already  | 
 | 13 | +    have a next node it is point to."""  | 
 | 14 | +    def insert_after(self, value):  | 
 | 15 | +        current_next = self.next  | 
 | 16 | +        self.next = ListNode(value, self, current_next)  | 
 | 17 | +        if current_next:  | 
 | 18 | +            current_next.prev = self.next  | 
 | 19 | + | 
 | 20 | +    """Wrap the given value in a ListNode and insert it  | 
 | 21 | +    before this node. Note that this node could already  | 
 | 22 | +    have a previous node it is point to."""  | 
 | 23 | +    def insert_before(self, value):  | 
 | 24 | +        current_prev = self.prev  | 
 | 25 | +        self.prev = ListNode(value, current_prev, self)  | 
 | 26 | +        if current_prev:  | 
 | 27 | +            current_prev.next = self.prev  | 
 | 28 | + | 
 | 29 | +    """Rearranges this ListNode's previous and next pointers  | 
 | 30 | +    accordingly, effectively deleting this ListNode."""  | 
 | 31 | +    def delete(self):  | 
 | 32 | +        if self.prev:  | 
 | 33 | +            self.prev.next = self.next  | 
 | 34 | +        if self.next:  | 
 | 35 | +            self.next.prev = self.prev  | 
 | 36 | + | 
 | 37 | + | 
 | 38 | +"""Our doubly-linked list class. It holds references to  | 
 | 39 | +the list's head and tail nodes."""  | 
 | 40 | + | 
 | 41 | + | 
 | 42 | +class DoublyLinkedList:  | 
 | 43 | +    def __init__(self, node=None):  | 
 | 44 | +        self.head = node  | 
 | 45 | +        self.tail = node  | 
 | 46 | +        self.length = 1 if node is not None else 0  | 
 | 47 | + | 
 | 48 | +    def __len__(self):  | 
 | 49 | +        return self.length  | 
 | 50 | + | 
 | 51 | +    """Wraps the given value in a ListNode and inserts it   | 
 | 52 | +    as the new head of the list. Don't forget to handle   | 
 | 53 | +    the old head node's previous pointer accordingly."""  | 
 | 54 | +    def add_to_head(self, value):  | 
 | 55 | +        new_node = ListNode(value, None, None)  | 
 | 56 | +        self.length += 1  | 
 | 57 | +        if not self.head and not self.tail:  | 
 | 58 | +            self.head = new_node  | 
 | 59 | +            self.tail = new_node  | 
 | 60 | +        else:  | 
 | 61 | +            new_node.next = self.head  | 
 | 62 | +            self.head.prev = new_node  | 
 | 63 | +            self.head = new_node  | 
 | 64 | + | 
 | 65 | +    """Removes the List's current head node, making the  | 
 | 66 | +    current head's next node the new head of the List.  | 
 | 67 | +    Returns the value of the removed Node."""  | 
 | 68 | +    def remove_from_head(self):  | 
 | 69 | +        value = self.head.value  | 
 | 70 | +        self.delete(self.head)  | 
 | 71 | +        return value  | 
 | 72 | + | 
 | 73 | +    """Wraps the given value in a ListNode and inserts it   | 
 | 74 | +    as the new tail of the list. Don't forget to handle   | 
 | 75 | +    the old tail node's next pointer accordingly."""  | 
 | 76 | +    def add_to_tail(self, value):  | 
 | 77 | +        new_node = ListNode(value, None, None)  | 
 | 78 | +        self.length += 1  | 
 | 79 | +        if not self.head and not self.tail:  | 
 | 80 | +            self.head = new_node  | 
 | 81 | +            self.tail = new_node  | 
 | 82 | +        else:  | 
 | 83 | +            new_node.prev = self.tail  | 
 | 84 | +            self.tail.next = new_node  | 
 | 85 | +            self.tail = new_node  | 
 | 86 | + | 
 | 87 | +    """Removes the List's current tail node, making the   | 
 | 88 | +    current tail's previous node the new tail of the List.  | 
 | 89 | +    Returns the value of the removed Node."""  | 
 | 90 | +    def remove_from_tail(self):  | 
 | 91 | +        value = self.tail.value  | 
 | 92 | +        self.delete(self.tail)  | 
 | 93 | +        return value  | 
 | 94 | + | 
 | 95 | +    """Removes the input node from its current spot in the   | 
 | 96 | +    List and inserts it as the new head node of the List."""  | 
 | 97 | +    def move_to_front(self, node):  | 
 | 98 | +        if node is self.head:  | 
 | 99 | +            return  | 
 | 100 | +        value = node.value  | 
 | 101 | +        self.delete(node)  | 
 | 102 | +        self.add_to_head(value)  | 
 | 103 | + | 
 | 104 | +    """Removes the input node from its current spot in the   | 
 | 105 | +    List and inserts it as the new tail node of the List."""  | 
 | 106 | +    def move_to_end(self, node):  | 
 | 107 | +        if node is self.tail:  | 
 | 108 | +            return  | 
 | 109 | +        value = node.value  | 
 | 110 | +        self.delete(node)  | 
 | 111 | +        self.add_to_tail(value)  | 
 | 112 | + | 
 | 113 | +    """Removes a node from the list and handles cases where  | 
 | 114 | +    the node was the head or the tail"""  | 
 | 115 | +    def delete(self, node):  | 
 | 116 | +        self.length -= 1  | 
 | 117 | +        if self.head is self.tail:  | 
 | 118 | +            self.head = None  | 
 | 119 | +            self.tail = None  | 
 | 120 | +        elif self.head is node:  | 
 | 121 | +            self.head = node.next  | 
 | 122 | +            node.delete()  | 
 | 123 | +        elif self.tail is node:  | 
 | 124 | +            self.tail = node.prev  | 
 | 125 | +            node.delete()  | 
 | 126 | +        else:  | 
 | 127 | +            node.delete()  | 
 | 128 | + | 
 | 129 | +    """Returns the highest value currently in the list"""  | 
 | 130 | +    def get_max(self):  | 
 | 131 | +        max_value = self.head.value  | 
 | 132 | +        current = self.head  | 
 | 133 | +        while current is not None:  | 
 | 134 | +            if current.value > max_value:  | 
 | 135 | +                max_value = current.value  | 
 | 136 | +            current = current.next  | 
 | 137 | + | 
 | 138 | +        return max_value  | 
0 commit comments