Skip to content

Fix doubly linked list algorithm #2062

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Aug 2, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
148 changes: 92 additions & 56 deletions data_structures/linked_list/doubly_linked_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,80 +5,116 @@
- Each link references the next link and the previous one.
- 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.
- 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"""


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):
self.head = None
self.tail = None
self.head = None # First node in list
self.tail = None # Last node in list

def __str__(self):
current = self.head
nodes = []
while current is not None:
nodes.append(current)
current = current.next
return " ".join(str(node) for node in nodes)

def insertHead(self, x):
newLink = Link(x) # Create a new link with a value attached to it
if self.isEmpty(): # Set the first element added to be the tail
self.tail = newLink
def insert_at_head(self, data):
new_node = Node(data)
if self.is_empty:
self.tail = new_node
self.head = new_node
else:
self.head.previous = new_node
new_node.next = self.head
self.head = new_node

def delete_head(self) -> str:
if self.is_empty:
return "List is empty"

head_data = self.head.data
if self.head.next:
self.head = self.head.next
self.head.previous = None

else: # If there is no next previous node
self.head = None
self.tail = None

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.head.previous = newLink # newLink <-- currenthead(head)
newLink.next = self.head # newLink <--> currenthead(head)
self.head = newLink # newLink(head) <--> oldhead

def deleteHead(self):
temp = self.head
self.head = self.head.next # oldHead <--> 2ndElement(head)
# 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):
newLink = Link(x)
newLink.next = None # currentTail(tail) newLink -->
self.tail.next = newLink # currentTail(tail) --> newLink -->
newLink.previous = self.tail # currentTail(tail) <--> newLink -->
self.tail = newLink # oldTail <--> newLink(tail) -->

def deleteTail(self):
temp = self.tail
self.tail = self.tail.previous # 2ndLast(tail) <--> oldTail --> None
self.tail.next = None # 2ndlast(tail) --> None
return temp

def delete(self, x):
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

while current.value != x: # Find the position to delete
current = current.next
while current.data != data: # Find the position to delete
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:
self.deleteHead()
self.delete_head()

elif current == self.tail:
self.deleteTail()
self.delete_tail()

else: # Before: 1 <--> 2(current) <--> 3
current.previous.next = current.next # 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

def display(self): # Prints contents of the list
current = self.head
while current is not None:
current.displayLink()
current = current.next
print()


class Link:
next = None # This points to the link in front of the new link
previous = None # This points to the link behind the new link

def __init__(self, x):
self.value = x
class Node:
def __init__(self, data):
self.data = data
self.previous = None
self.next = None

def displayLink(self):
print(f"{self.value}", end=" ")
def __str__(self):
return f"{self.data}"