From 90989f052ae8912930cfeedae66900c3bb933f45 Mon Sep 17 00:00:00 2001 From: Himanshu Bhatnagar <33115688+Himan10@users.noreply.github.com> Date: Thu, 2 Jan 2020 00:48:35 +0530 Subject: [PATCH 1/6] Create deque_doubly.py Implementing Deque ADT using Doubly Linked List.... --- data_structures/linked_list/deque_doubly.py | 88 +++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 data_structures/linked_list/deque_doubly.py diff --git a/data_structures/linked_list/deque_doubly.py b/data_structures/linked_list/deque_doubly.py new file mode 100644 index 000000000000..83d5d20b7e9e --- /dev/null +++ b/data_structures/linked_list/deque_doubly.py @@ -0,0 +1,88 @@ +""" +Implementing Deque using DoublyLinkedList ... +Operations: + 1. insertion in the front -> O(1) + 2. insertion in the end -> O(1) + 3. remove fron the front -> O(1) + 4. remove from the end -> O(1) +""" + +class _DoublyLinkedBase: + """ A Private class (to be inherited) """ + class _Node: + __slots__ = '_prev', '_data', '_next' + def __init__(self, link_p, element, link_n): + self._prev = link_p + self._data = element + self._next = link_n + + def has_next_and_prev(self): + return " Prev -> {0}, Next -> {1}".format(self._prev != None, self._next != None) + + def __init__(self): + self._header = self._Node(None, None, None) + self._trailer = self._Node(None, None, None) + self._header._next = self._trailer + self._trailer._prev = self._header + self._size = 0 + + def __len__(self): + return self._size + + def is_empty(self): + return self.__len__() == 0 + + def _insert(self, predecessor, e, successor): + # Create new_node by setting it's prev.link -> header + # setting it's next.link -> trailer + new_node = self._Node(predecessor, e, successor) + predecessor._next = new_node + successor._prev = new_node + self._size += 1 + return self + + def _delete(self, node): + predecessor = node._prev + successor = node._next + + predecessor._next = successor + successor._prev = predecessor + self._size -= 1 + temp = node._data + node._prev = node._next = node._data = None + del node + return temp + +class LinkedDeque(_DoublyLinkedBase): + + def first(self): + """ return first element """ + if self.is_empty(): + raise Exception('Duffer!! first insert something') + return self._header._next._data + + def last(self): + """ return last element """ + if self.is_empty(): + raise Exception('Duffer!! first insert something') + return self._trailer._prev._data + + ### DEque Insert Operations (At the front, At the end) ### + + def add_first(self, element): + return self._insert(self._header, element, self._header._next) + + def add_last(self, element): + return self._insert(self._trailer._prev, element, self._trailer) + + ### DEqueu Remove Operations (At the front, At the end) ### + + def remove_first(self): + if self.is_empty(): + raise Exception('NOthing to Lose') + return self._delete(self._header._next) + + def remove_last(self): + if self.is_empty(): + raise Exception('NOthing to Lose') + return self._delete(self._trailer._prev) From b30e62bf295eb7152616a3cc0581eeefd07ed999 Mon Sep 17 00:00:00 2001 From: Himanshu Bhatnagar <33115688+Himan10@users.noreply.github.com> Date: Thu, 2 Jan 2020 01:04:19 +0530 Subject: [PATCH 2/6] Update deque_doubly.py --- data_structures/linked_list/deque_doubly.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/data_structures/linked_list/deque_doubly.py b/data_structures/linked_list/deque_doubly.py index 83d5d20b7e9e..a56d16bb9df7 100644 --- a/data_structures/linked_list/deque_doubly.py +++ b/data_structures/linked_list/deque_doubly.py @@ -58,13 +58,13 @@ class LinkedDeque(_DoublyLinkedBase): def first(self): """ return first element """ if self.is_empty(): - raise Exception('Duffer!! first insert something') + raise Exception('List is empty') return self._header._next._data def last(self): """ return last element """ if self.is_empty(): - raise Exception('Duffer!! first insert something') + raise Exception('List is empty') return self._trailer._prev._data ### DEque Insert Operations (At the front, At the end) ### @@ -79,10 +79,10 @@ def add_last(self, element): def remove_first(self): if self.is_empty(): - raise Exception('NOthing to Lose') + raise Exception('List is empty') return self._delete(self._header._next) def remove_last(self): if self.is_empty(): - raise Exception('NOthing to Lose') + raise Exception('List is empty') return self._delete(self._trailer._prev) From 31d405702949e482d04395b1cafb28094503730b Mon Sep 17 00:00:00 2001 From: Himanshu Bhatnagar <33115688+Himan10@users.noreply.github.com> Date: Thu, 2 Jan 2020 02:01:41 +0530 Subject: [PATCH 3/6] Update deque_doubly.py Adding doctest --- data_structures/linked_list/deque_doubly.py | 60 ++++++++++++++++++++- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/data_structures/linked_list/deque_doubly.py b/data_structures/linked_list/deque_doubly.py index a56d16bb9df7..43210b30d0c6 100644 --- a/data_structures/linked_list/deque_doubly.py +++ b/data_structures/linked_list/deque_doubly.py @@ -56,13 +56,37 @@ def _delete(self, node): class LinkedDeque(_DoublyLinkedBase): def first(self): - """ return first element """ + """ return first element + >>> d = LinkedDeque() + >>> d.add_first('A') # doctest: +ELLIPSIS + >> d.first() + 'A' + >>> d.add_first('B') # doctest: +ELLIPSIS + >> d.first() + 'B' + """ if self.is_empty(): raise Exception('List is empty') return self._header._next._data def last(self): - """ return last element """ + """ return last element + >>> d = LinkedDeque() + >>> d.last() + Traceback (most recent call last): + ... + Exception: List is empty + >>> d.add_last('A') # doctest: +ELLIPSIS + >> d.last() + 'A' + >>> d.add_last('B') # doctest: +ELLIPSIS + >> d.last() + 'B' + """ if self.is_empty(): raise Exception('List is empty') return self._trailer._prev._data @@ -70,19 +94,51 @@ def last(self): ### DEque Insert Operations (At the front, At the end) ### def add_first(self, element): + """ insertion in the front + >>> d = LinkedDeque() + >>> d.add_first('AV') # doctest: +ELLIPSIS + >> d = LinkedDeque() + >>> d.add_last('A') # doctest: +ELLIPSIS + >> d = LinkedDeque() + >>> d.remove_first() + Traceback (most recent call last): + ... + Exception: List is empty + >>> d.add_first('A') # doctest: +ELLIPSIS + >> d.remove_first() + 'A' + """ if self.is_empty(): raise Exception('List is empty') return self._delete(self._header._next) def remove_last(self): + """ removal in the end + >>> d = LinkedDeque() + >>> d.remove_last() + Traceback (most recent call last): + ... + Exception: List is empty + >>> d.add_first('A') # doctest: +ELLIPSIS + >> d.remove_last() + 'A' + """ if self.is_empty(): raise Exception('List is empty') return self._delete(self._trailer._prev) From 643b36f31b634c03e6878da64d6eec7af6ad0524 Mon Sep 17 00:00:00 2001 From: Himanshu Bhatnagar <33115688+Himan10@users.noreply.github.com> Date: Sun, 5 Jan 2020 14:20:29 +0530 Subject: [PATCH 4/6] Update doctest of deque_doubly.py --- data_structures/linked_list/deque_doubly.py | 48 +++++++++------------ 1 file changed, 21 insertions(+), 27 deletions(-) diff --git a/data_structures/linked_list/deque_doubly.py b/data_structures/linked_list/deque_doubly.py index 43210b30d0c6..ce6f9f8ecf1f 100644 --- a/data_structures/linked_list/deque_doubly.py +++ b/data_structures/linked_list/deque_doubly.py @@ -58,13 +58,9 @@ class LinkedDeque(_DoublyLinkedBase): def first(self): """ return first element >>> d = LinkedDeque() - >>> d.add_first('A') # doctest: +ELLIPSIS - >> d.first() + >>> d.add_first('A').first() 'A' - >>> d.add_first('B') # doctest: +ELLIPSIS - >> d.first() + >>> d.add_first('B').first() 'B' """ if self.is_empty(): @@ -74,17 +70,9 @@ def first(self): def last(self): """ return last element >>> d = LinkedDeque() - >>> d.last() - Traceback (most recent call last): - ... - Exception: List is empty - >>> d.add_last('A') # doctest: +ELLIPSIS - >> d.last() + >>> d.add_last('A').last() 'A' - >>> d.add_last('B') # doctest: +ELLIPSIS - >> d.last() + >>> d.add_last('B').last() 'B' """ if self.is_empty(): @@ -95,17 +83,15 @@ def last(self): def add_first(self, element): """ insertion in the front - >>> d = LinkedDeque() - >>> d.add_first('AV') # doctest: +ELLIPSIS - >> LinkedDeque().add_first('AV').first() + 'AV' """ return self._insert(self._header, element, self._header._next) def add_last(self, element): """ insertion in the end - >>> d = LinkedDeque() - >>> d.add_last('A') # doctest: +ELLIPSIS - >> LinkedDeque().add_last('B').last() + 'B' """ return self._insert(self._trailer._prev, element, self._trailer) @@ -114,31 +100,39 @@ def add_last(self, element): def remove_first(self): """ removal from the front >>> d = LinkedDeque() + >>> d.is_empty() + True >>> d.remove_first() Traceback (most recent call last): ... - Exception: List is empty + IndexError: remove_first from empty list >>> d.add_first('A') # doctest: +ELLIPSIS >> d.remove_first() 'A' + >>> d.is_empty() + True """ if self.is_empty(): - raise Exception('List is empty') + raise IndexError('remove_first from empty list') return self._delete(self._header._next) def remove_last(self): """ removal in the end >>> d = LinkedDeque() + >>> d.is_empty() + True >>> d.remove_last() Traceback (most recent call last): ... - Exception: List is empty + IndexError: remove_first from empty list >>> d.add_first('A') # doctest: +ELLIPSIS >> d.remove_last() 'A' + >>> d.is_empty() + True """ if self.is_empty(): - raise Exception('List is empty') - return self._delete(self._trailer._prev) + raise IndexError('remove_first from empty list') + return self._delete(self._trailer._prev From c483ce6bf41ebd51a3c623f80daca5f5db90b5b9 Mon Sep 17 00:00:00 2001 From: Himanshu Bhatnagar <33115688+Himan10@users.noreply.github.com> Date: Sun, 5 Jan 2020 14:23:58 +0530 Subject: [PATCH 5/6] Update deque_doubly.py --- data_structures/linked_list/deque_doubly.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data_structures/linked_list/deque_doubly.py b/data_structures/linked_list/deque_doubly.py index ce6f9f8ecf1f..8c60a34c520b 100644 --- a/data_structures/linked_list/deque_doubly.py +++ b/data_structures/linked_list/deque_doubly.py @@ -135,4 +135,4 @@ def remove_last(self): """ if self.is_empty(): raise IndexError('remove_first from empty list') - return self._delete(self._trailer._prev + return self._delete(self._trailer._prev) From f6471c833af3d01cfaa4bdea8c7d70d69a9ebd0e Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Sun, 5 Jan 2020 10:43:32 +0100 Subject: [PATCH 6/6] linked_list. --- data_structures/linked_list/deque_doubly.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data_structures/linked_list/deque_doubly.py b/data_structures/linked_list/deque_doubly.py index 8c60a34c520b..d858333220e9 100644 --- a/data_structures/linked_list/deque_doubly.py +++ b/data_structures/linked_list/deque_doubly.py @@ -107,7 +107,7 @@ def remove_first(self): ... IndexError: remove_first from empty list >>> d.add_first('A') # doctest: +ELLIPSIS - >> d.remove_first() 'A' >>> d.is_empty() @@ -127,7 +127,7 @@ def remove_last(self): ... IndexError: remove_first from empty list >>> d.add_first('A') # doctest: +ELLIPSIS - >> d.remove_last() 'A' >>> d.is_empty()