Skip to content

Commit

Permalink
CircularLinkedList Added
Browse files Browse the repository at this point in the history
  • Loading branch information
prshnt19 committed Mar 2, 2020
1 parent 5b4217a commit 7bb4305
Show file tree
Hide file tree
Showing 3 changed files with 155 additions and 4 deletions.
3 changes: 2 additions & 1 deletion pydatastructs/linear_data_structures/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from .linked_lists import (
SinglyLinkedList,
DoublyLinkedList,
SinglyCircularLinkedList
SinglyCircularLinkedList,
DoublyCircularLinkedList
)
__all__.extend(linked_lists.__all__)
119 changes: 117 additions & 2 deletions pydatastructs/linear_data_structures/linked_lists.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
__all__ = [
'SinglyLinkedList',
'DoublyLinkedList',
'SinglyCircularLinkedList'
'SinglyCircularLinkedList',
'DoublyCircularLinkedList'
]

class LinkedList(object):
Expand Down Expand Up @@ -584,7 +585,6 @@ def insert_at(self, index, data):
self.head.next = self.head
new_node = self.__getitem__(index)
if index == 0:
self.head = new_node
self.tail.next = new_node
if new_node.next == self.head:
self.tail = new_node
Expand All @@ -611,3 +611,118 @@ def extract(self, index):
elif index == 0:
self.tail.next = self.head
return node

class DoublyCircularLinkedList(DoublyLinkedList):
"""
Represents Doubly Circular Linked List
Examples
========
>>> from pydatastructs import DoublyCircularLinkedList
>>> dcll = DoublyCircularLinkedList()
>>> dcll.append(6)
>>> dcll[0].data
6
>>> dcll.head.data
6
>>> dcll.append(5)
>>> dcll.append_left(2)
>>> print(dcll)
[2, 6, 5]
>>> dcll[0].data = 7.2
>>> dcll.extract(1).data
6
>>> print(dcll)
[7.2, 5]
References
==========
.. [1] https://en.wikipedia.org/wiki/Doubly_linked_list
"""
def insert_after(self, prev_node, data):
"""
Inserts a new node after the prev_node.
Parameters
==========
prev_node: LinkedListNode
The node after which the
new node is to be inserted.
data
Any valid data to be stored in the node.
"""
super(DoublyCircularLinkedList, self).insert_after(prev_node, data)
if prev_node.next.next == self.head:
self.tail = prev_node.next

def insert_before(self, next_node, data):
"""
Inserts a new node before the next_node.
Parameters
==========
next_node: LinkedListNode
The node before which the
new node is to be inserted.
data
Any valid data to be stored in the node.
"""
super(DoublyCircularLinkedList, self).insert_before(next_node,data)
if next_node == self.head:
self.head = next_node.prev

def insert_at(self, index, data):
"""
Inserts a new node at the input index.
Parameters
==========
index: int
An integer satisfying python indexing properties.
data
Any valid data to be stored in the node.
"""
super(DoublyCircularLinkedList, self).insert_at(index, data)
if self.size == 1:
self.head.next = self.head
self.head.prev = self.head
new_node = self.__getitem__(index)
if index == 0:
self.tail.next = new_node
new_node.prev = self.tail
if new_node.next == self.head:
self.tail = new_node
new_node.next = self.head
self.head.prev = new_node

def extract(self, index):
"""
Extracts the node at the index of the list.
Parameters
==========
index: int
An integer satisfying python indexing properties.
Returns
=======
current_node: LinkedListNode
The node at index i.
"""
node = super(DoublyCircularLinkedList, self).extract(index)
if self.tail is None:
self.head = None
elif index == 0:
self.tail.next = self.head
return node
37 changes: 36 additions & 1 deletion pydatastructs/linear_data_structures/tests/test_linked_lists.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from pydatastructs.linear_data_structures import DoublyLinkedList, SinglyLinkedList, SinglyCircularLinkedList
from pydatastructs.linear_data_structures import DoublyLinkedList, SinglyLinkedList, SinglyCircularLinkedList, DoublyCircularLinkedList
from pydatastructs.utils.raises_util import raises
import copy, random

Expand Down Expand Up @@ -102,3 +102,38 @@ def test_SinglyCircularLinkedList():
scll_copy.extract(index)
assert str(scll_copy) == "[]"
assert raises(ValueError, lambda: scll_copy.extract(1))

def test_DoublyCircularLinkedList():
random.seed(1000)
dcll = DoublyCircularLinkedList()
assert raises(IndexError, lambda: dcll[2])
dcll.append_left(5)
dcll.append(1)
dcll.append_left(2)
dcll.append(3)
dcll.insert_after(dcll[-1], 4)
dcll.insert_after(dcll[2], 6)
dcll.insert_before(dcll[4], 1)
dcll.insert_before(dcll[0], 7)
dcll.insert_at(0, 2)
dcll.insert_at(-1, 9)
dcll.extract(2)
dcll.extract(0)
dcll.extract(-1)
dcll[-2].data = 0
assert str(dcll) == "[7, 5, 1, 6, 1, 0, 9]"
assert len(dcll) == 7
assert raises(IndexError, lambda: dcll.insert_at(8, None))
assert raises(IndexError, lambda: dcll.extract(20))
dcll_copy = copy.deepcopy(dcll)
for i in range(len(dcll)):
if i%2 == 0:
dcll.pop_left()
else:
dcll.pop_right()
assert str(dcll) == "[]"
for _ in range(len(dcll_copy)):
index = random.randint(0, len(dcll_copy) - 1)
dcll_copy.extract(index)
assert str(dcll_copy) == "[]"
assert raises(ValueError, lambda: dcll_copy.extract(1))

0 comments on commit 7bb4305

Please sign in to comment.