|
5 | 5 | - Each link references the next link and the previous one.
|
6 | 6 | - A Doubly Linked List (DLL) contains an extra pointer, typically called previous
|
7 | 7 | pointer, together with next pointer and data which are there in singly linked list.
|
8 |
| - - Advantages over SLL - IT can be traversed in both forward and backward direction., |
| 8 | + - Advantages over SLL - It can be traversed in both forward and backward direction. |
9 | 9 | Delete operation is more efficient"""
|
10 | 10 |
|
11 | 11 |
|
12 |
| -class LinkedList: # making main class named linked list |
| 12 | +class LinkedList: |
| 13 | + """ |
| 14 | + >>> linked_list = LinkedList() |
| 15 | + >>> linked_list.insert_at_head("a") |
| 16 | + >>> linked_list.insert_at_tail("b") |
| 17 | + >>> linked_list.delete_tail() |
| 18 | + 'b' |
| 19 | + >>> linked_list.is_empty |
| 20 | + False |
| 21 | + >>> linked_list.delete_head() |
| 22 | + 'a' |
| 23 | + >>> linked_list.is_empty |
| 24 | + True |
| 25 | + """ |
| 26 | + |
13 | 27 | def __init__(self):
|
14 |
| - self.head = None |
15 |
| - self.tail = None |
| 28 | + self.head = None # First node in list |
| 29 | + self.tail = None # Last node in list |
| 30 | + |
| 31 | + def __str__(self): |
| 32 | + current = self.head |
| 33 | + nodes = [] |
| 34 | + while current is not None: |
| 35 | + nodes.append(current) |
| 36 | + current = current.next |
| 37 | + return " ".join(str(node) for node in nodes) |
16 | 38 |
|
17 |
| - def insertHead(self, x): |
18 |
| - newLink = Link(x) # Create a new link with a value attached to it |
19 |
| - if self.isEmpty(): # Set the first element added to be the tail |
20 |
| - self.tail = newLink |
| 39 | + def insert_at_head(self, data): |
| 40 | + new_node = Node(data) |
| 41 | + if self.is_empty: |
| 42 | + self.tail = new_node |
| 43 | + self.head = new_node |
| 44 | + else: |
| 45 | + self.head.previous = new_node |
| 46 | + new_node.next = self.head |
| 47 | + self.head = new_node |
| 48 | + |
| 49 | + def delete_head(self) -> str: |
| 50 | + if self.is_empty: |
| 51 | + return "List is empty" |
| 52 | + |
| 53 | + head_data = self.head.data |
| 54 | + if self.head.next: |
| 55 | + self.head = self.head.next |
| 56 | + self.head.previous = None |
| 57 | + |
| 58 | + else: # If there is no next previous node |
| 59 | + self.head = None |
| 60 | + self.tail = None |
| 61 | + |
| 62 | + return head_data |
| 63 | + |
| 64 | + def insert_at_tail(self, data): |
| 65 | + new_node = Node(data) |
| 66 | + if self.is_empty: |
| 67 | + self.tail = new_node |
| 68 | + self.head = new_node |
21 | 69 | else:
|
22 |
| - self.head.previous = newLink # newLink <-- currenthead(head) |
23 |
| - newLink.next = self.head # newLink <--> currenthead(head) |
24 |
| - self.head = newLink # newLink(head) <--> oldhead |
25 |
| - |
26 |
| - def deleteHead(self): |
27 |
| - temp = self.head |
28 |
| - self.head = self.head.next # oldHead <--> 2ndElement(head) |
29 |
| - # oldHead --> 2ndElement(head) nothing pointing at it so the old head will be |
30 |
| - # removed |
31 |
| - self.head.previous = None |
32 |
| - if self.head is None: |
33 |
| - self.tail = None # if empty linked list |
34 |
| - return temp |
35 |
| - |
36 |
| - def insertTail(self, x): |
37 |
| - newLink = Link(x) |
38 |
| - newLink.next = None # currentTail(tail) newLink --> |
39 |
| - self.tail.next = newLink # currentTail(tail) --> newLink --> |
40 |
| - newLink.previous = self.tail # currentTail(tail) <--> newLink --> |
41 |
| - self.tail = newLink # oldTail <--> newLink(tail) --> |
42 |
| - |
43 |
| - def deleteTail(self): |
44 |
| - temp = self.tail |
45 |
| - self.tail = self.tail.previous # 2ndLast(tail) <--> oldTail --> None |
46 |
| - self.tail.next = None # 2ndlast(tail) --> None |
47 |
| - return temp |
48 |
| - |
49 |
| - def delete(self, x): |
| 70 | + self.tail.next = new_node |
| 71 | + new_node.previous = self.tail |
| 72 | + self.tail = new_node |
| 73 | + |
| 74 | + def delete_tail(self) -> str: |
| 75 | + if self.is_empty: |
| 76 | + return "List is empty" |
| 77 | + |
| 78 | + tail_data = self.tail.data |
| 79 | + if self.tail.previous: |
| 80 | + self.tail = self.tail.previous |
| 81 | + self.tail.next = None |
| 82 | + else: # if there is no previous node |
| 83 | + self.head = None |
| 84 | + self.tail = None |
| 85 | + |
| 86 | + return tail_data |
| 87 | + |
| 88 | + def delete(self, data) -> str: |
50 | 89 | current = self.head
|
51 | 90 |
|
52 |
| - while current.value != x: # Find the position to delete |
53 |
| - current = current.next |
| 91 | + while current.data != data: # Find the position to delete |
| 92 | + if current.next: |
| 93 | + current = current.next |
| 94 | + else: # We have reached the end an no value matches |
| 95 | + return "No data matching given value" |
54 | 96 |
|
55 | 97 | if current == self.head:
|
56 |
| - self.deleteHead() |
| 98 | + self.delete_head() |
57 | 99 |
|
58 | 100 | elif current == self.tail:
|
59 |
| - self.deleteTail() |
| 101 | + self.delete_tail() |
60 | 102 |
|
61 | 103 | else: # Before: 1 <--> 2(current) <--> 3
|
62 | 104 | current.previous.next = current.next # 1 --> 3
|
63 | 105 | current.next.previous = current.previous # 1 <--> 3
|
| 106 | + return data |
64 | 107 |
|
65 |
| - def isEmpty(self): # Will return True if the list is empty |
| 108 | + @property |
| 109 | + def is_empty(self): # return True if the list is empty |
66 | 110 | return self.head is None
|
67 | 111 |
|
68 |
| - def display(self): # Prints contents of the list |
69 |
| - current = self.head |
70 |
| - while current is not None: |
71 |
| - current.displayLink() |
72 |
| - current = current.next |
73 |
| - print() |
74 |
| - |
75 |
| - |
76 |
| -class Link: |
77 |
| - next = None # This points to the link in front of the new link |
78 |
| - previous = None # This points to the link behind the new link |
79 | 112 |
|
80 |
| - def __init__(self, x): |
81 |
| - self.value = x |
| 113 | +class Node: |
| 114 | + def __init__(self, data): |
| 115 | + self.data = data |
| 116 | + self.previous = None |
| 117 | + self.next = None |
82 | 118 |
|
83 |
| - def displayLink(self): |
84 |
| - print(f"{self.value}", end=" ") |
| 119 | + def __str__(self): |
| 120 | + return f"{self.data}" |
0 commit comments