Skip to content

Linked list stack implemented #139

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

Closed
wants to merge 19 commits into from
Closed
Show file tree
Hide file tree
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,4 @@ __pycache__/
.idea/
build/
dist/
venv/
64 changes: 62 additions & 2 deletions pydatastructs/miscellaneous_data_structures/stack.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from pydatastructs.linear_data_structures import DynamicOneDimensionalArray
from pydatastructs.utils.misc_util import _check_type, NoneType
from pydatastructs.linear_data_structures import DynamicOneDimensionalArray, SinglyLinkedList
from pydatastructs.utils.misc_util import _check_type, NoneType, LinkedListNode
from copy import deepcopy as dc

__all__ = [
Expand Down Expand Up @@ -51,6 +51,10 @@ def __new__(cls, implementation='array', **kwargs):
return ArrayStack(
kwargs.get('items', None),
kwargs.get('dtype', int))
elif implementation == 'linkedlist':
return LinkedListStack(
kwargs.get('items', None),
kwargs.get('dtype', int))
raise NotImplementedError(
"%s hasn't been implemented yet."%(implementation))

Expand Down Expand Up @@ -109,3 +113,59 @@ def __str__(self):
Used for printing.
"""
return str(self.items._data)


class LinkedListStack(Stack):

def __new__(cls, items=None, dtype=NoneType):
obj = object.__new__(cls)
obj.stack = SinglyLinkedList()
obj._dtype = dtype
obj.size = 0
if items is None:
pass
elif type(items) in (list, tuple):
if len(items) != 0 and dtype is NoneType:
obj._dtype = type(items[0])
for x in items:
if type(x) == obj._dtype:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to use _check_type from misc_utils.py here?

obj.stack.append_left(x)
obj.size+=1
else:
raise TypeError("Expected %s but got %s"%(obj._dtype, type(x)))
Comment on lines +134 to +135
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

else:
raise TypeError("Expected type: list/tuple")
Comment on lines +136 to +137
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please do input filtering at the entry point of a function/method.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved refactored the new method, check it its good enough

obj.top = obj.stack.head
return obj

def push(self, x):
if self._dtype is NoneType:
self._dtype = type(x)
elif type(x) is not self._dtype:
raise TypeError("Expected %s but got %s"%(self._dtype, type(x)))
self.size += 1
self.stack.append_left(x)
if self.top is None:
self.top = self.stack.head

def pop(self):
if self.is_empty:
raise ValueError("Stack is empty")
self.size -= 1
return_value = self.stack.pop_left()
self.top = self.stack.head
return return_value

@property
def is_empty(self):
return self.size == 0
Comment on lines +160 to +161
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use, self.top here to figure out whether the stack is empty?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will lose consistency with LinkedListQueue if i change it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like that LinkedListQueue needs some changes in it's __new__ method. Can you please address similar comments there as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure will solve it in different PR.


@property
def peek(self):
return self.top

def __len__(self):
return self.size

def __str__(self):
return str(self.stack)
22 changes: 20 additions & 2 deletions pydatastructs/miscellaneous_data_structures/tests/test_stack.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

def test_Stack():

s = Stack()
s = Stack(implementation='array')
s.push(1)
s.push(2)
s.push(3)
Expand All @@ -15,6 +15,24 @@ def test_Stack():
assert s.pop() == 1
assert s.is_empty is True
assert raises(ValueError, lambda : s.pop())
_s = Stack(items=[1, 2, 3])
_s = Stack(implementation='array',items=[1, 2, 3])
assert str(_s) == '[1, 2, 3]'
assert raises(NotImplementedError, lambda: Stack(implementation=''))

s1 = Stack(implementation='linkedlist')
s1.push(1)
assert raises(TypeError, lambda: s1.push('a'))
assert raises(TypeError, lambda: Stack(implementation='linkedlist', items=[0], dtype=str))
assert raises(TypeError, lambda: Stack(implementation='linkedlist', items={0, 1}))
s1 = Stack(implementation='linkedlist', items = [0, 1])
s1.push(2)
s1.push(3)
assert str(s1) == '[3, 2, 1, 0]'
assert len(s1) == 4
assert s1.pop().data == 3
assert s1.pop().data == 2
assert len(s1) == 2
assert s1.pop().data == 1
assert s1.pop().data == 0
assert len(s1) == 0
raises(ValueError, lambda: s1.pop())
Loading