Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
9958c72
Start to tests
jay-tyler Jun 29, 2015
003b538
Merge branch 'feature/queue' of github.com:jonathanstallings/data-str…
jay-tyler Jun 29, 2015
80ae888
working on parametrizing tests; need to figure out how to do tuple un…
jay-tyler Jun 29, 2015
5c29a7d
current
jay-tyler Jun 30, 2015
b94675e
Merge branch 'feature/queue' of github.com:jonathanstallings/data-str…
jay-tyler Jun 30, 2015
8368ec4
Merge branch 'feature/queue' of github.com:jonathanstallings/data-str…
jay-tyler Jun 30, 2015
fdb9882
Should have a pretty decent set of tests now. Sorry for the extra wait.
jay-tyler Jun 30, 2015
2e1698a
Added to README.md
jay-tyler Jun 30, 2015
393b9a7
Remove comment
jonathanstallings Jun 30, 2015
abbe916
Fix style
jonathanstallings Jun 30, 2015
d6c337f
Fix dequeue method tail handling.
jonathanstallings Jun 30, 2015
1ea16a7
Add test for dequeue
jonathanstallings Jun 30, 2015
b344433
Implement linked list as iterable; need to refactor other data struct…
jonathanstallings Jun 30, 2015
3a074a4
Add first pass for double link list
jonathanstallings Jun 30, 2015
6178d66
Complete old methods.
jonathanstallings Jun 30, 2015
79efd8f
Sketch docstrings for new methods
jonathanstallings Jun 30, 2015
e216908
Complete basic methods, need to fix head and tail management.
jonathanstallings Jun 30, 2015
5fcba41
Mark further points for review
jonathanstallings Jun 30, 2015
5e3f65b
Refactor remove
jonathanstallings Jun 30, 2015
dc92d03
Complete methods shift and pop
jonathanstallings Jun 30, 2015
fc30c32
Add comments
jonathanstallings Jun 30, 2015
c15b898
Fix bugs
jonathanstallings Jun 30, 2015
0eb644b
Bugfix: remove method head case
jonathanstallings Jun 30, 2015
0f51e36
tests for insert, append, pop, shift, instantiation
jay-tyler Jul 1, 2015
2fcb0ff
Tests finished; now inlcudes remove() tests; also added ValueError ex…
jay-tyler Jul 1, 2015
2d48426
Improve docstrings, exceptions; fix none case for remove method.
jonathanstallings Jul 1, 2015
77bc64e
Fix queue references dued to linked list refactor
jonathanstallings Jul 5, 2015
fa8f06f
Merge pull request #12 from jonathanstallings/feature/doublelinklist_…
jonathanstallings Jul 5, 2015
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
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,11 @@ Available methods include:
* push(value)
* pop()

##Dequeque
The Dequeue data class is a first-in-last-out data structure built via encapsulation of a LinkedList.
Available methods inlude:
* enqueque(value)
* dequeque()
* len()

See the doc strings for implementation details.
158 changes: 158 additions & 0 deletions double_link_list.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
from __future__ import unicode_literals


class Node(object):

def __init__(self, val, prev=None, next_=None):
self.val = val
self.prev = prev
self.next = next_

def __repr__(self):
"""Print representation of node."""
return "{val}".format(val=self.val)


class DoubleLinkList(object):
"""Class for a doubly-linked list."""
def __init__(self, iterable=()):
self._current = None
self.head = None
self.tail = None
self.length = 0
for val in reversed(iterable):
self.insert(val)

def __repr__(self):
"""Print representation of DoubleLinkList."""
node = self.head
output = ""
for node in self:
output += "{!r}, ".format(node.val)
return "({})".format(output.rstrip(' ,'))

def __len__(self):
return self.length

def __iter__(self):
if self.head is not None:
self._current = self.head
return self

def next(self):
if self._current is None:
raise StopIteration
node = self._current
self._current = self._current.next
return node

def size(self):
"""Return current length of DoubleLinkList."""
return len(self)

def search(self, search_val):
"""Return the node containing val if present, else None.

args:
search_val: the value to search by

returns: a node object or None
"""
for node in self:
if node.val == search_val:
return node
else:
return None

def remove(self, search_val):
"""Remove the first node from list matching the search value.

args:
search_val: the val to be removed
"""
search_node = self.search(search_val)

if search_node == self.head:
self.head = search_node.next
try:
self.head.prev = None
except AttributeError:
pass
self.length -= 1
elif search_node == self.tail:
self.tail = search_node.prev
try:
self.tail.next = None
except AttributeError:
pass
self.length -= 1
else:
for node in self:
if node == search_node:
node.prev.next = node.next
node.next.prev = node.prev
self.length -= 1
return None
raise ValueError('value not in list')

def insert(self, val):
"""Insert value at head of list.

args:
val: the value to add
"""
old_head = self.head
self.head = Node(val, prev=None, next_=old_head)
if old_head is None:
self.tail = self.head
else:
old_head.prev = self.head
self.length += 1
return None

def append(self, val):
"""Append a node with value to end of list.

args:
val: the value to add
"""
old_tail = self.tail
self.tail = Node(val, prev=old_tail, next_=None)
if old_tail is None:
self.head = self.tail
else:
old_tail.next = self.tail
self.length += 1
return None

def pop(self):
"""Pop the first val off the head and return it."""
if self.head is None:
raise IndexError('pop from empty list')
else:
to_return = self.head
self.head = to_return.next
try:
self.head.prev = None
except AttributeError: # List is now empty
self.tail = None
self.length -= 1
return to_return.val

def shift(self):
"""Remove the last value from the tail and return."""
if self.tail is None:
raise IndexError('pop from empty list')
else:
to_return = self.tail
self.tail = to_return.prev
try:
self.tail.next = None
except AttributeError: # List is now empty
self.head = None
self.length -= 1
return to_return.val

def display(self):
"""Shows representation of DoubleLinkList."""
return repr(self)
95 changes: 40 additions & 55 deletions linked_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,99 +15,84 @@ def __repr__(self):
class LinkedList(object):
"""Class for a singly-linked list."""
def __init__(self, iterable=()):
self.header = None
self._current = None
self.head = None
self.length = 0
for val in reversed(iterable):
self.insert(val)

def __repr__(self):
"""Print representation of LinkedList."""
node = self.header
node = self.head
output = ""
while node is not None:
for node in self:
output += "{!r}, ".format(node.val)
node = node.next
return "({})".format(output.rstrip(' ,'))

def __len__(self):
return self.length

def __iter__(self):
if self.head is not None:
self._current = self.head
return self

def next(self):
if self._current is None:
raise StopIteration
node = self._current
self._current = self._current.next
return node

def insert(self, val):
"""Insert value at head of LinkedList.

args:
val: the value to add
"""
self.header = Node(val, self.header)
self.head = Node(val, self.head)
self.length += 1
return None

def pop(self):
"""Pop the first val off the head and return it."""
if self.header is None:
if self.head is None:
raise IndexError
else:
to_return = self.header
self.header = to_return.next
to_return = self.head
self.head = to_return.next
self.length -= 1
return to_return.val

def size(self):
"""Return current length of LinkedList."""
return self.length
return len(self)

def search(self, val):
def search(self, search_val):
"""Return the node containing val if present, else None.

args:
val: the value to add
"""
node, _ = self._find(val)
return node

def remove(self, node):
"""Remove given node from list, return None.
search_val: the value to search by

args:
node: the node to be removed
returns: a node object or None
"""
node_to_remove, left_neighbor = self._find(node.val, node)

if self.header == node_to_remove:
self.pop()

for node in self:
if node.val == search_val:
return node
else:
left_neighbor.next = node_to_remove.next

return None
return None

def display(self):
"""Print LinkedList as Tuple literal"""
return self.__repr__()

def _find(self, val, node=None):
"""
Return a node and previous by matching against value or node.
def remove(self, search_node):
"""Remove given node from list, return None.

args:
val: the value to find
node: optionally, node to match identity against
search_node: the node to be removed
"""
matched = False
node_inspected = self.header
left_node = None

while not matched:
# Interrogate each Node
if node_inspected.val == val:
if node is not None:
if node_inspected is node:
matched = True
break
else:
matched = True
break
# Keeping track of node to left; incrementing node
elif node_inspected.next is not None:
left_node, node_inspected = node_inspected, node_inspected.next
else:
for node in self:
if node.next == search_node:
node.next = node.next.next
return None

return node_inspected, left_node
def display(self):
"""Shows representation of LinkedList."""
return repr(self)
8 changes: 5 additions & 3 deletions queue.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class Queue():

def __init__(self, iterable=()):
self.other = LinkedList()
self.other.header = None
self.other.head = None
self.other.tail = None
self.other.length = 0
for val in (iterable):
Expand All @@ -25,16 +25,18 @@ def enqueue(self, value):
args:
value: The value to add to the queue
"""
new_node = Node(value) # Need to fix this logic
new_node = Node(value)
if self.other.tail is None:
self.other.header = self.other.tail = new_node
self.other.head = self.other.tail = new_node
else:
self.other.tail.next = new_node
self.other.tail = new_node
self.other.length += 1

def dequeue(self):
"""Remove and return a value from the head of the queue."""
if len(self) == 1:
self.other.tail = None
return self.other.pop()

def size(self):
Expand Down
Loading