Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
0eb5388
adding deque
JSchatzman Dec 19, 2016
1ec202e
rename and add append and appendleft
JSchatzman Dec 19, 2016
b1a7e39
adding pop and popleft
JSchatzman Dec 19, 2016
ebdc1d9
removing old methods and declaration of nodes
JSchatzman Dec 19, 2016
227fad8
readding node assignments
JSchatzman Dec 19, 2016
c3f6d0e
added test functions for initializing a deque and adding data using a…
clair3st Dec 19, 2016
44867f4
Merge branch 'dequeue' of https://github.com/JSchatzman/data_structur…
clair3st Dec 19, 2016
080f0ff
added peek left and size methods to deque
clair3st Dec 19, 2016
83faccb
final testing
JSchatzman Dec 19, 2016
32d380a
create branch
JSchatzman Dec 20, 2016
04b54d5
adding some nitial methods
JSchatzman Dec 20, 2016
fd47ed0
fixing init and change swap logic
JSchatzman Dec 20, 2016
f7e3673
created test for parent index function and push function
clair3st Dec 20, 2016
845ef41
Merge branch 'binheap' of https://github.com/JSchatzman/data_structur…
clair3st Dec 20, 2016
7156729
changed attribute to be data not heap
clair3st Dec 20, 2016
1ab9cdb
added push test
clair3st Dec 20, 2016
210f7c3
fix my swap
JSchatzman Dec 20, 2016
4fa9a2a
sort merge conflict
JSchatzman Dec 20, 2016
3a7fb24
handle case if new value is lowest
JSchatzman Dec 20, 2016
98c5567
added test for inserting a minimum value
clair3st Dec 20, 2016
7b20fa7
Merge branch 'binheap' of https://github.com/JSchatzman/data_structur…
clair3st Dec 20, 2016
7be5853
finish testing except for pop
JSchatzman Dec 21, 2016
5ed10b7
added find min child function and pop function
clair3st Dec 21, 2016
f65fcc0
handled merge
clair3st Dec 21, 2016
268e27d
finising up test and pop
JSchatzman Dec 21, 2016
9d72595
Update README.md
clair3st Dec 21, 2016
7717626
added test coverage
clair3st Dec 21, 2016
6091173
Merge branch 'binheap' of https://github.com/JSchatzman/data_structur…
clair3st Dec 21, 2016
bba614e
added data for initialization
clair3st Dec 29, 2016
e52ad0b
added conditions for iterable initialisation
clair3st Dec 29, 2016
e94acc7
added new test coverage
clair3st Dec 29, 2016
7d707a1
refactored bin heap code to be more DRY
clair3st Dec 29, 2016
14dd341
added tests for pop for a whole list
clair3st Dec 29, 2016
162b005
updated setup
clair3st Dec 29, 2016
51d6ad5
added type check to heap initialization
clair3st Dec 31, 2016
1ba8d25
updated setup with module names
clair3st Dec 31, 2016
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
128 changes: 121 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,128 @@
# data_structures
# Data-Structures

##### This repository contains python implementations of various fundamental abstract data structures. These include:
###This repo holds sample code for a number of classic data structures implemented in Python.

##Singly-Linked List in Python
- **Module:** linked_list.py
- **Tests:** test_linked_list.py

##### 1. Linked List (src/linked_list.py)
Our list implementation supports the following methods:

##### 2. Stack (src/stack.py)
- **push(val)** will insert the value ‘val’ at the head of the list
- **pop()** will pop the first value off the head of the list and return it.
- **size()** will return the length of the list
- **search(val)** will return the node containing ‘val’ in the list, if present, else None
- **remove(node)** will remove the given node from the list, wherever it might be (node must be an item in the list)
- **display()** will return a unicode string representing the list as if it were a Python tuple literal: “(12, ‘sam’, 37, ‘tango’)”

##### 3. Doubly Linked List (src/dll.py)

###### The Linked List and Doubly Linked List are similar but have slightly different use cases. The Doubly Linked List allows traversal forwards and backwards. This could be used in an image slider or a browser's history memory, for example. The Doubly Linked List cannot append to or shift away items from the end of the list. The Linked List cannot move backwards or edit the end of the list. It is, however, lighter weight than the Doubly Linked List.
##Stack using Class Composition
- **Module:** stack.py
- **Tests:** test_stack.py
- **Resources Used:** https://codefellows.github.io/sea-python-401d5/lectures/inheritance_v_composition.html

##### 4. Queue (src/queue.py)
Our stack implementation supports the following methods:

- **push(value)** - Adds a value to the stack. The parameter is the value to be added to the stack.
- **pop()** - Removes a value from the stack and returns that value. If the stack is empty, attempts to call pop should raise an appropriate Python exception class.


##Double linked list
- **Module:** dll.py
- **Tests:** test_dll.py
- **Resources Used** https://en.wikipedia.org/wiki/Doubly_linked_list

Our double linked list implementation supports the following methods:

- **push(val)** - will insert the value ‘val’ at the head of the list
- **append(val)** - will append the value ‘val’ at the tail of the list
- **pop()** - will pop the first value off the head of the list and return it.
- **shift()** - will remove the last value from the tail of the list and return it.
- **remove(val)** - will remove the first instance of ‘val’ found in the list, starting from the head. If ‘val’ is not present, it will raise an appropriate Python exception.


##Queue
- **Module:** queue.py
- **Tests:** test_queue.py
- **Resources Used** http://www.princeton.edu/~achaney/tmve/wiki100k/docs/Queue_(data_structure).html

Our queue implementation supports the following methods:

- **enqueue(value)** - adds value to the queue
- **dequeue()** - removes the correct item from the queue and returns its value (should raise an error if the queue is empty)
- **peek()** - returns the next value in the queue without dequeueing it. If the queue is empty, returns None
- **size()** - return the size of the queue. Should return 0 if the queue is empty.

##Deque
- **Module:** deque.py
- **Tests:** deque.py
- **Resources Used** https://codefellows.github.io/sea-python-401d5/lectures/deque.html

Our dequeue implementation supports the following methods:

- **append(val)** - adds value to the end of the deque
- **appendleft(val)** - adds a value to the front of the deque
- **pop()** - removes a value from the end of the deque and returns it (raises an exception if the deque is empty)
- **popleft()** - removes a value from the front of the deque and returns it (raises an exception if the deque is empty)
- **peek()** - returns the next value that would be returned by pop but leaves the value in the deque (returns None if the deque is empty)
- **peekleft()** - returns the next value that would be returned by popleft but leaves the value in the deque (returns None if the deque is empty)
- **size()** - returns the count of items in the queue (returns 0 if the queue is empty)


##Binary Heap - Minimum
- **Module:** heap.py
- **Tests:** test_heap.py
- **Resources Used** https://interactivepython.org/runestone/static/pythonds/Trees/BinaryHeapImplementation.html

Our binary heap implementation supports the following methods:

- **push()** - puts a new value into the heap, maintaining the heap property.
- **pop()** - removes the “top” value in the heap, maintaining the heap property.


#Testing Coverage:
```
---------- coverage: platform darwin, python 2.7.11-final-0 ----------
Name Stmts Miss Cover Missing
-------------------------------------------------------
src/deque.py 33 6 82% 49-51, 56-58
src/dll.py 70 1 99% 17
src/heap.py 38 0 100%
src/linked_list.py 58 3 95% 16, 26, 34
src/queue.py 19 0 100%
src/stack.py 13 0 100%
src/test_deque.py 68 0 100%
src/test_dll.py 82 0 100%
src/test_heap.py 54 0 100%
src/test_linked_list.py 74 0 100%
src/test_queue.py 64 0 100%
src/test_stack.py 48 3 94% 88-90
-------------------------------------------------------
TOTAL 621 13 98%


========================== 93 passed in 0.29 seconds ==


======================================================= 88 passed in 0.43 seconds
---------- coverage: platform darwin, python 3.5.2-final-0 -----------
Name Stmts Miss Cover Missing
-------------------------------------------------------
src/deque.py 33 6 82% 49-51, 56-58
src/dll.py 70 1 99% 17
src/heap.py 38 0 100%
src/linked_list.py 58 3 95% 16, 26, 34
src/queue.py 19 0 100%
src/stack.py 13 0 100%
src/test_deque.py 68 0 100%
src/test_dll.py 82 0 100%
src/test_heap.py 54 0 100%
src/test_linked_list.py 74 0 100%
src/test_queue.py 64 0 100%
src/test_stack.py 48 3 94% 88-90
-------------------------------------------------------
TOTAL 621 13 98%


========================== 93 passed in 0.43 seconds
```
10 changes: 5 additions & 5 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
"""The setup for Mailroom distribution."""
"""The setup for data structures."""

from setuptools import setup

setup(
name='data_structures',
description='Implementation of Data Structures.',
description='Implementation of Data Structures in Python.',
version=0.1,
author='Jordan Schatzman, Julien Wilson',
author_email='j.schatzman@outlook.com, julienawilson@gmail.com',
author='Jordan Schatzman, Julien Wilson, Claire Gatenby',
author_email='j.schatzman@outlook.com, julienawilson@gmail.com, clairejgatenby@gmail.com',
license='MIT',
package_dir={'': 'src'},
py_modules=['linked_list', 'stack'],
py_modules=['linked_list', 'stack', 'dll', 'deque', 'queue', 'heap'],
extras_require={'test': ['pytest', 'pytest-watch', 'pytest-cov', 'tox']},
)
71 changes: 71 additions & 0 deletions src/deque.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
"""Implementation of Queue."""

from dll import DoublyLinkedList


class Deque(object):
"""Class implementation of queue.

append(val): adds value to the end of the deque.
appendleft(val): adds a value to the front of the deque.
pop(): removes a value from the end of the deque and returns it
(raises an exception if the deque is empty)
popleft(): removes a value from the front of the deque and returns it
(raises an exception if the deque is empty)
peek(): returns the next value that would be returned by pop but
leaves the value in the deque (returns None if the deque is empty)
peekleft(): returns the next value that would be returned by popleft
but leaves the value in the deque (returns None if the deque
is empty)
size(): returns the count of items in the queue (returns 0 if the
queue is empty)

"""

def __init__(self, iterable=None):
"""Instatiate Queue."""
self.dll = DoublyLinkedList(iterable)
self.head_node = self.dll.head_node
self.tail_node = self.dll.tail_node
self.length = self.dll.length

def append(self, contents):
"""Add value to the end of the deque."""
self.dll.append(contents)
self.head_node = self.dll.head_node
self.tail_node = self.dll.tail_node
self.length = self.dll.length

def appendleft(self, contents):
"""Add value to the front of the deque."""
self.dll.push(contents)
self.head_node = self.dll.head_node
self.tail_node = self.dll.tail_node
self.length = self.dll.length

def pop(self):
"""Remove and return the current tail node."""
return self.dll.shift()
self.head_node = self.dll.head_node
self.tail_node = self.dll.tail_node
self.length = self.dll.length

def popleft(self):
"""Remove and return the current head node."""
return self.dll.pop()
self.head_node = self.dll.head_node
self.tail_node = self.dll.tail_node
self.length = self.dll.length

def peek(self):
"""Display but don't remove the contents of tail node."""
return self.dll.tail_node.contents

def peekleft(self):
"""Display but don't remove the contents of head node."""
return self.dll.head_node.contents

def size(self):
"""Return the count of items in the queue."""
return self.length

58 changes: 58 additions & 0 deletions src/heap.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
"""Implementation of heap."""


class Heap(object):
"""Create heap class.

push(): puts a new value into the heap,
pop(): removes the top value in the heap,
"""

def __init__(self, val=''):
"""Instantiate a heap."""
self.data = []
try:
for item in val:
self.push(item)
except TypeError:
if type(val) == bool or val == Exception:
raise TypeError('Incorrect datatype for Heap object.')
self.data.append(val)

def push(self, val):
"""Add value to the end of the data."""
self.data.append(val)
self._swap_nodes_up(len(self.data) - 1)

def pop(self):
"""Remove head of the heap."""
if len(self.data) == 0:
raise IndexError('Cannot pop a empty heap!')
val = self.data[0]
self.data[0] = self.data[-1]
self.data.pop()
self._swap_nodes_down(0)
return val

def _swap_nodes_up(self, idx):
"""Swap parent and child nodes if greater."""
if idx == 0:
return 0
parent_index = (idx - 1) // 2
if self.data[idx] < self.data[parent_index]:
self.data[idx], self.data[parent_index] = self.data[parent_index], self.data[idx]
self._swap_nodes_up(parent_index)

def _swap_nodes_down(self, idx):
"""Swap nodes up until meets minheap."""
child1 = (2 * idx) + 1
if child1 >= len(self.data):
return 0
child2 = child1 + 1
try:
lowest_child = child1 if self.data[child1] < self.data[child2] else child2
except IndexError:
lowest_child = child1
if self.data[idx] > self.data[lowest_child]:
self.data[idx], self.data[lowest_child] = self.data[lowest_child], self.data[idx]
self._swap_nodes_down(lowest_child)
Loading