Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
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 .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
language: python
python:
- "2.7"
install: "pip install -r requirements.txt"
script: py.test
11 changes: 8 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,14 @@
Code Fellows Dev Accelerator: This repository will be for implementations of classic data structures in python.


parens.py:
## parens.py:
Includes a function balanceness() that takes string and determines if it is 'open', 'balanced', or 'broken', depending on the sequence of parenthesis contained. 'Open', 'balanced', and 'broken' are respectively determined as more leading '('s than ')'s, equal number of leading '(' and ')', and any sequence including ')' that do not have a preceding '('. 'Open' strings are represented by returning a 1, 'balanced' by 0, and 'broken' by -1, with an emptry string being considered 'balanced'.

bst.py:
## bst.py:
Binary search tree is a tree where each node has a left child and a right
child and every left child is smaller and every right child is larger. We implement it with a dictionary where each key is the value of the node and each value has three things in it, depth, left child and right child.
child and every left child is smaller and every right child is larger. We implement it with a dictionary where each key is the value of the node and each value has three things in it, depth, left child and right child. This module includes a Bst class and the following functions: insert, balance, contains, size, depth, get\_dot. It also includes generators that traverse the tree in order: in\_order, pre\_order, post\_order, and breadth\_first.



## Resources:
[Wikipedia Breadth First Search](en.wikipedia.org/wiki/Breadth-first_search)
74 changes: 66 additions & 8 deletions bst.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/usr/bin/env python
import random
import subprocess
from collections import deque


class Bst(object):
Expand All @@ -17,6 +18,14 @@ def __init__(self, value=None):
self._size += 1
self._depth += 1

def left(self, current):
return self.tree[current].get('left')


def right(self, current):
return self.tree[current].get('right')


Copy link

Choose a reason for hiding this comment

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

These methods will be helpful!

def insert(self, value):
"""Insert a node with value in order.

Expand All @@ -34,10 +43,10 @@ def insert(self, value):
if current == value:
return
if current < value:
traverse = self.tree[current].get('right')
traverse = self.right(current)
child = 'right'
else:
traverse = self.tree[current].get('left')
traverse = self.left(current)
child = 'left'
if traverse is None:
#actual insert
Expand All @@ -49,7 +58,6 @@ def insert(self, value):
return
current = traverse


def balance(self):
"""Returns the balance of the tree:

Expand Down Expand Up @@ -91,7 +99,6 @@ def get_dot(self):
)
))


def _get_dot(self, current):
"""recursively prepare a dot graph entry for this node."""
left = self.tree[current].get('left')
Expand All @@ -113,14 +120,65 @@ def _get_dot(self, current):
yield "\tnull%s [shape=point];" % r
yield "\t%s -> null%s;" % (current, r)

def in_order(self, current='start'):
"""
Generator that traverses the binary tree in order.
"""
if current == 'start':
current = self.top
Copy link

Choose a reason for hiding this comment

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

What if your BST is containing strings, like perhaps one might if you were building a dictionary for spell-checking or something. What if the word start is in your dictionary?

if current is not None:
for node in self.in_order(self.left(current)):
yield node
yield current
for node in self.in_order(self.right(current)):
yield node


def pre_order(self, current='dutch'):
"""Generator that traverses the binary tree pre order."""
if current == 'dutch':
current = self.top
if current is not None:
yield current
for node in self.pre_order(self.left(current)):
yield node
for node in self.pre_order(self.right(current)):
yield node

def post_order(self, current='dutch'):
"""Generator that traverses the binary tree post order."""
if current == 'dutch':
current = self.top
if current is not None:
for node in self.post_order(self.left(current)):
yield node
for node in self.post_order(self.right(current)):
yield node
yield current

def breadth_first(self):
"""Generator that traverses the binary tree in breadth first order."""
q1 = deque()
q1.appendleft(self.top)
current = self.top
while q1:
current = q1.pop()
if self.left(current) is not None:
q1.appendleft(self.left(current))
if self.right(current) is not None:
q1.appendleft(self.right(current))
yield current


def main():
"""Best case and worst case are the same."""
tree = Bst()
for num in reversed(range(10)):
tree.insert(num)
for num in range(10, 15):
tree.insert(num)
inserts = [7, 4, 11, 2, 9, 6, 12, 5, 13, 0, 10, 8, 3, 1]
for i in inserts:
tree.insert(i)
print tree.tree
# for num in enumerate(tree.pre_order()):
# print num
dot_graph = tree.get_dot()
t = subprocess.Popen(["dot", "-Tpng"], stdin=subprocess.PIPE)
t.communicate(dot_graph)
Expand Down
5 changes: 3 additions & 2 deletions linked_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ def insert(self, val):
Set .data attribute to val and rearrange the list so the head is
the new node with a reference to the old head.
"""
# if isinstance(val, unicode):
# val = val.encode('utf-8')
self.head = List_Node(val, self.head)
self._size += 1

Expand Down Expand Up @@ -104,7 +106,7 @@ def display_prep(self):
while temp:
dummy = temp.data
if isinstance(temp.data, str or unicode):
dummy = "'{}'".format(dummy.encode('utf-8'))
dummy = "'{}'".format(dummy)

if temp is self.head:
output = "{}{}".format(output, dummy)
Expand All @@ -113,5 +115,4 @@ def display_prep(self):
output = "{}, {}".format(output, dummy)
temp = temp.next


return output + ")"
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
py==1.4.26
pytest==2.6.4
55 changes: 55 additions & 0 deletions test_bst.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ def test_depth_tree(filled_tree):
t = filled_tree
assert t.depth() == 10


def test_balance(empty_tree, filled_tree):
t = empty_tree
assert t.balance() == 0
Expand All @@ -65,6 +66,7 @@ def test_balance(empty_tree, filled_tree):
t = filled_tree
assert t.balance() == -5


def test_contains(filled_tree):
t = filled_tree
for num in reversed(range(10)):
Expand All @@ -75,8 +77,51 @@ def test_contains(filled_tree):
assert t.contains(num) is False


def test_in_order(filled_tree):
tree = filled_tree
gen = tree.in_order()
expected_order = range(0, 14)
for i in expected_order:
j = gen.next()
print str(i) + '=' + str(j)
assert i == j
with pytest.raises(StopIteration):
gen.next()


def test_pre_order(filled_tree):
tree = filled_tree
gen = tree.pre_order()
expected_order = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 10, 11, 12, 13]
for i in expected_order:
j = gen.next()
print str(i) + '=' + str(j)
assert i == j
with pytest.raises(StopIteration):
gen.next()

def test_post_order(filled_tree):
tree = filled_tree
gen = tree.post_order()
expected_order = [0, 1, 2, 3, 4, 5, 6, 7, 8, 13, 12, 11, 10, 9]
for i in expected_order:
j = gen.next()
print str(i) + '=' + str(j)
assert i == j
with pytest.raises(StopIteration):
gen.next()


def test_breadth_first_order(filled_tree):
tree = filled_tree
expected_order = [9, 8, 10, 7, 11, 6, 12, 5, 13, 4, 3, 2, 1, 0]
for place, item in enumerate(tree.breadth_first()):
assert expected_order[place] == item


@pytest.fixture(scope='function')
def filled_tree():
"""Upside down V Shaped Tree"""
tree = bst.Bst()
for num in reversed(range(10)):
tree.insert(num)
Expand All @@ -85,6 +130,16 @@ def filled_tree():
return tree


@pytest.fixture(scope='function')
def filled_tree_2():
"""Tree with lots of branches"""
inserts = [7, 4, 11, 2, 9, 6, 12, 5, 13, 0, 10, 8, 3, 1]
tree = bst.Bst()
for val in inserts:
tree.insert(val)
return tree


@pytest.fixture(scope='function')
def empty_tree():
tree = bst.Bst()
Expand Down
1 change: 1 addition & 0 deletions test_linked_list.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
# test constructor
from linked_list import List_Node
from linked_list import Linked_List
Expand Down