Fix doubly linked list algorithm ()

* Fix doubly linked list algorithm

* Fix bug with insert_at_tail method

Create __str__() method for Node class and LinkedList class

* Simplify __str__() of LinkedList

Returns empty string if there are no elements in the list

* Fix description
This commit is contained in:
TheSuperNoob 2020-08-02 17:55:18 +02:00 committed by GitHub
parent b875f66f00
commit b2e8672f02
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -5,80 +5,116 @@
- Each link references the next link and the previous one. - Each link references the next link and the previous one.
- A Doubly Linked List (DLL) contains an extra pointer, typically called previous - A Doubly Linked List (DLL) contains an extra pointer, typically called previous
pointer, together with next pointer and data which are there in singly linked list. pointer, together with next pointer and data which are there in singly linked list.
- Advantages over SLL - IT can be traversed in both forward and backward direction., - Advantages over SLL - It can be traversed in both forward and backward direction.
Delete operation is more efficient""" Delete operation is more efficient"""
class LinkedList: # making main class named linked list class LinkedList:
"""
>>> linked_list = LinkedList()
>>> linked_list.insert_at_head("a")
>>> linked_list.insert_at_tail("b")
>>> linked_list.delete_tail()
'b'
>>> linked_list.is_empty
False
>>> linked_list.delete_head()
'a'
>>> linked_list.is_empty
True
"""
def __init__(self): def __init__(self):
self.head = None self.head = None # First node in list
self.tail = None self.tail = None # Last node in list
def insertHead(self, x): def __str__(self):
newLink = Link(x) # Create a new link with a value attached to it current = self.head
if self.isEmpty(): # Set the first element added to be the tail nodes = []
self.tail = newLink while current is not None:
nodes.append(current)
current = current.next
return " ".join(str(node) for node in nodes)
def insert_at_head(self, data):
new_node = Node(data)
if self.is_empty:
self.tail = new_node
self.head = new_node
else: else:
self.head.previous = newLink # newLink <-- currenthead(head) self.head.previous = new_node
newLink.next = self.head # newLink <--> currenthead(head) new_node.next = self.head
self.head = newLink # newLink(head) <--> oldhead self.head = new_node
def deleteHead(self): def delete_head(self) -> str:
temp = self.head if self.is_empty:
self.head = self.head.next # oldHead <--> 2ndElement(head) return "List is empty"
# oldHead --> 2ndElement(head) nothing pointing at it so the old head will be
# removed
self.head.previous = None
if self.head is None:
self.tail = None # if empty linked list
return temp
def insertTail(self, x): head_data = self.head.data
newLink = Link(x) if self.head.next:
newLink.next = None # currentTail(tail) newLink --> self.head = self.head.next
self.tail.next = newLink # currentTail(tail) --> newLink --> self.head.previous = None
newLink.previous = self.tail # currentTail(tail) <--> newLink -->
self.tail = newLink # oldTail <--> newLink(tail) -->
def deleteTail(self): else: # If there is no next previous node
temp = self.tail self.head = None
self.tail = self.tail.previous # 2ndLast(tail) <--> oldTail --> None self.tail = None
self.tail.next = None # 2ndlast(tail) --> None
return temp
def delete(self, x): return head_data
def insert_at_tail(self, data):
new_node = Node(data)
if self.is_empty:
self.tail = new_node
self.head = new_node
else:
self.tail.next = new_node
new_node.previous = self.tail
self.tail = new_node
def delete_tail(self) -> str:
if self.is_empty:
return "List is empty"
tail_data = self.tail.data
if self.tail.previous:
self.tail = self.tail.previous
self.tail.next = None
else: # if there is no previous node
self.head = None
self.tail = None
return tail_data
def delete(self, data) -> str:
current = self.head current = self.head
while current.value != x: # Find the position to delete while current.data != data: # Find the position to delete
current = current.next if current.next:
current = current.next
else: # We have reached the end an no value matches
return "No data matching given value"
if current == self.head: if current == self.head:
self.deleteHead() self.delete_head()
elif current == self.tail: elif current == self.tail:
self.deleteTail() self.delete_tail()
else: # Before: 1 <--> 2(current) <--> 3 else: # Before: 1 <--> 2(current) <--> 3
current.previous.next = current.next # 1 --> 3 current.previous.next = current.next # 1 --> 3
current.next.previous = current.previous # 1 <--> 3 current.next.previous = current.previous # 1 <--> 3
return data
def isEmpty(self): # Will return True if the list is empty @property
def is_empty(self): # return True if the list is empty
return self.head is None return self.head is None
def display(self): # Prints contents of the list
current = self.head
while current is not None:
current.displayLink()
current = current.next
print()
class Node:
def __init__(self, data):
self.data = data
self.previous = None
self.next = None
class Link: def __str__(self):
next = None # This points to the link in front of the new link return f"{self.data}"
previous = None # This points to the link behind the new link
def __init__(self, x):
self.value = x
def displayLink(self):
print(f"{self.value}", end=" ")