Skip to content

Commit b212a59

Browse files
Himan10cclauss
andcommitted
Create deque_doubly.py (TheAlgorithms#1652)
* Create deque_doubly.py Implementing Deque ADT using Doubly Linked List.... * Update deque_doubly.py * Update deque_doubly.py Adding doctest * Update doctest of deque_doubly.py * Update deque_doubly.py * linked_list. Co-authored-by: Christian Clauss <cclauss@me.com>
1 parent 1cc817b commit b212a59

File tree

1 file changed

+138
-0
lines changed

1 file changed

+138
-0
lines changed
+138
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
"""
2+
Implementing Deque using DoublyLinkedList ...
3+
Operations:
4+
1. insertion in the front -> O(1)
5+
2. insertion in the end -> O(1)
6+
3. remove fron the front -> O(1)
7+
4. remove from the end -> O(1)
8+
"""
9+
10+
class _DoublyLinkedBase:
11+
""" A Private class (to be inherited) """
12+
class _Node:
13+
__slots__ = '_prev', '_data', '_next'
14+
def __init__(self, link_p, element, link_n):
15+
self._prev = link_p
16+
self._data = element
17+
self._next = link_n
18+
19+
def has_next_and_prev(self):
20+
return " Prev -> {0}, Next -> {1}".format(self._prev != None, self._next != None)
21+
22+
def __init__(self):
23+
self._header = self._Node(None, None, None)
24+
self._trailer = self._Node(None, None, None)
25+
self._header._next = self._trailer
26+
self._trailer._prev = self._header
27+
self._size = 0
28+
29+
def __len__(self):
30+
return self._size
31+
32+
def is_empty(self):
33+
return self.__len__() == 0
34+
35+
def _insert(self, predecessor, e, successor):
36+
# Create new_node by setting it's prev.link -> header
37+
# setting it's next.link -> trailer
38+
new_node = self._Node(predecessor, e, successor)
39+
predecessor._next = new_node
40+
successor._prev = new_node
41+
self._size += 1
42+
return self
43+
44+
def _delete(self, node):
45+
predecessor = node._prev
46+
successor = node._next
47+
48+
predecessor._next = successor
49+
successor._prev = predecessor
50+
self._size -= 1
51+
temp = node._data
52+
node._prev = node._next = node._data = None
53+
del node
54+
return temp
55+
56+
class LinkedDeque(_DoublyLinkedBase):
57+
58+
def first(self):
59+
""" return first element
60+
>>> d = LinkedDeque()
61+
>>> d.add_first('A').first()
62+
'A'
63+
>>> d.add_first('B').first()
64+
'B'
65+
"""
66+
if self.is_empty():
67+
raise Exception('List is empty')
68+
return self._header._next._data
69+
70+
def last(self):
71+
""" return last element
72+
>>> d = LinkedDeque()
73+
>>> d.add_last('A').last()
74+
'A'
75+
>>> d.add_last('B').last()
76+
'B'
77+
"""
78+
if self.is_empty():
79+
raise Exception('List is empty')
80+
return self._trailer._prev._data
81+
82+
### DEque Insert Operations (At the front, At the end) ###
83+
84+
def add_first(self, element):
85+
""" insertion in the front
86+
>>> LinkedDeque().add_first('AV').first()
87+
'AV'
88+
"""
89+
return self._insert(self._header, element, self._header._next)
90+
91+
def add_last(self, element):
92+
""" insertion in the end
93+
>>> LinkedDeque().add_last('B').last()
94+
'B'
95+
"""
96+
return self._insert(self._trailer._prev, element, self._trailer)
97+
98+
### DEqueu Remove Operations (At the front, At the end) ###
99+
100+
def remove_first(self):
101+
""" removal from the front
102+
>>> d = LinkedDeque()
103+
>>> d.is_empty()
104+
True
105+
>>> d.remove_first()
106+
Traceback (most recent call last):
107+
...
108+
IndexError: remove_first from empty list
109+
>>> d.add_first('A') # doctest: +ELLIPSIS
110+
<linked_list.deque_doubly.LinkedDeque object at ...
111+
>>> d.remove_first()
112+
'A'
113+
>>> d.is_empty()
114+
True
115+
"""
116+
if self.is_empty():
117+
raise IndexError('remove_first from empty list')
118+
return self._delete(self._header._next)
119+
120+
def remove_last(self):
121+
""" removal in the end
122+
>>> d = LinkedDeque()
123+
>>> d.is_empty()
124+
True
125+
>>> d.remove_last()
126+
Traceback (most recent call last):
127+
...
128+
IndexError: remove_first from empty list
129+
>>> d.add_first('A') # doctest: +ELLIPSIS
130+
<linked_list.deque_doubly.LinkedDeque object at ...
131+
>>> d.remove_last()
132+
'A'
133+
>>> d.is_empty()
134+
True
135+
"""
136+
if self.is_empty():
137+
raise IndexError('remove_first from empty list')
138+
return self._delete(self._trailer._prev)

0 commit comments

Comments
 (0)