Skip to content

Update Linked Stack #3625

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 3 commits into from
Oct 23, 2020
Merged
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
5 changes: 5 additions & 0 deletions DIRECTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,10 @@
* [Sdbm](https://github.com/TheAlgorithms/Python/blob/master/hashes/sdbm.py)
* [Sha1](https://github.com/TheAlgorithms/Python/blob/master/hashes/sha1.py)

## Knapsack
* [Knapsack](https://github.com/TheAlgorithms/Python/blob/master/knapsack/knapsack.py)
* [Test Knapsack](https://github.com/TheAlgorithms/Python/blob/master/knapsack/test_knapsack.py)

## Linear Algebra
* Src
* [Lib](https://github.com/TheAlgorithms/Python/blob/master/linear_algebra/src/lib.py)
Expand Down Expand Up @@ -502,6 +506,7 @@
* [Magicdiamondpattern](https://github.com/TheAlgorithms/Python/blob/master/other/magicdiamondpattern.py)
* [Markov Chain](https://github.com/TheAlgorithms/Python/blob/master/other/markov_chain.py)
* [Max Sum Sliding Window](https://github.com/TheAlgorithms/Python/blob/master/other/max_sum_sliding_window.py)
* [Median Of Two Arrays](https://github.com/TheAlgorithms/Python/blob/master/other/median_of_two_arrays.py)
* [Nested Brackets](https://github.com/TheAlgorithms/Python/blob/master/other/nested_brackets.py)
* [Palindrome](https://github.com/TheAlgorithms/Python/blob/master/other/palindrome.py)
* [Password Generator](https://github.com/TheAlgorithms/Python/blob/master/other/password_generator.py)
Expand Down
134 changes: 112 additions & 22 deletions data_structures/stacks/linked_stack.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
""" A Stack using a Linked List like structure """
from typing import Any, Optional
""" A Stack using a linked list like structure """
from typing import Any


class Node:
def __init__(self, data: Any, next: Optional["Node"] = None):
self.data: Any = data
self.next: Optional["Node"] = next
def __init__(self, data):
self.data = data
self.next = None

def __str__(self):
return f"{self.data}"


class LinkedStack:
Expand All @@ -19,7 +22,7 @@ class LinkedStack:
>>> stack.push(5)
>>> stack.push(9)
>>> stack.push('python')
>>> stack.is_empty();
>>> stack.is_empty()
False
>>> stack.pop()
'python'
Expand All @@ -39,29 +42,116 @@ class LinkedStack:
"""

def __init__(self) -> None:
self.top: Optional[Node] = None
self.top = None

def __iter__(self):
node = self.top
while node:
yield node.data
node = node.next

def __str__(self):
"""
>>> stack = LinkedStack()
>>> stack.push("c")
>>> stack.push("b")
>>> stack.push("a")
>>> str(stack)
'a->b->c'
"""
return "->".join([str(item) for item in self])

def __len__(self):
"""
>>> stack = LinkedStack()
>>> len(stack) == 0
True
>>> stack.push("c")
>>> stack.push("b")
>>> stack.push("a")
>>> len(stack) == 3
True
"""
return len(tuple(iter(self)))

def is_empty(self) -> bool:
""" returns boolean describing if stack is empty """
"""
>>> stack = LinkedStack()
>>> stack.is_empty()
True
>>> stack.push(1)
>>> stack.is_empty()
False
"""
return self.top is None

def push(self, item: Any) -> None:
""" append item to top of stack """
node: Node = Node(item)
if self.is_empty():
self.top = node
else:
# each node points to the item "lower" in the stack
"""
>>> stack = LinkedStack()
>>> stack.push("Python")
>>> stack.push("Java")
>>> stack.push("C")
>>> str(stack)
'C->Java->Python'
"""
node = Node(item)
if not self.is_empty():
node.next = self.top
self.top = node
self.top = node

def pop(self) -> Any:
""" returns and removes item at top of stack """
"""
>>> stack = LinkedStack()
>>> stack.pop()
Traceback (most recent call last):
...
IndexError: pop from empty stack
>>> stack.push("c")
>>> stack.push("b")
>>> stack.push("a")
>>> stack.pop() == 'a'
True
>>> stack.pop() == 'b'
True
>>> stack.pop() == 'c'
True
"""
if self.is_empty():
raise IndexError("pop from empty stack")
else:
# "remove" element by having top point to the next one
assert isinstance(self.top, Node)
node: Node = self.top
self.top = node.next
return node.data
assert isinstance(self.top, Node)
pop_node = self.top
self.top = self.top.next
return pop_node.data

def peek(self) -> Any:
"""
>>> stack = LinkedStack()
>>> stack.push("Java")
>>> stack.push("C")
>>> stack.push("Python")
>>> stack.peek()
'Python'
"""
if self.is_empty():
raise IndexError("peek from empty stack")
return self.top.data

def clear(self) -> None:
"""
>>> stack = LinkedStack()
>>> stack.push("Java")
>>> stack.push("C")
>>> stack.push("Python")
>>> str(stack)
'Python->C->Java'
>>> stack.clear()
>>> len(stack) == 0
True
"""
self.top = None


if __name__ == "__main__":
from doctest import testmod

testmod()