From b524234c439ef8fe73bd9362945d21cbddaf0cec Mon Sep 17 00:00:00 2001 From: Matthew Lee Date: Thu, 5 Mar 2015 13:46:47 -0800 Subject: [PATCH 01/17] Merge. --- bst.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bst.py b/bst.py index 6aea93c..35df399 100755 --- a/bst.py +++ b/bst.py @@ -108,7 +108,7 @@ def main(): for num in range(10, 15): tree.insert(num) dot_graph = tree.get_dot() - t = subprocess.Popen(["dot", "-Tpng", 'test.png'], stdin=subprocess.PIPE) + t = subprocess.Popen(["dot", "-Tpng"], stdin=subprocess.PIPE) import pdb; pdb.set_trace() t.communicate(dot_graph) From 996e65e118a3dabfc1a75d20c9f73050d9a4be9f Mon Sep 17 00:00:00 2001 From: Matthew Lee Date: Thu, 5 Mar 2015 14:54:16 -0800 Subject: [PATCH 02/17] I understand what I'm getting from a call on in_order() is a generator... --- bst.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/bst.py b/bst.py index 269710d..2cdd739 100755 --- a/bst.py +++ b/bst.py @@ -111,6 +111,16 @@ def _get_dot(self, current): yield "\tnull%s [shape=point];" % r yield "\t%s -> null%s;" % (current, r) + def in_order(self, current='dutch'): + if current == 'dutch': + current = self.top + if current: + for value in self.in_order(self.tree[current].get('left')): + yield value + yield current + for value in self.in_order(self.tree[current].get('right')): + yield value + def main(): """Best case and worst case are the same.""" @@ -119,9 +129,11 @@ def main(): tree.insert(num) for num in range(10, 15): tree.insert(num) + for thing in tree.in_order(): + print thing dot_graph = tree.get_dot() t = subprocess.Popen(["dot", "-Tpng"], stdin=subprocess.PIPE) - t.communicate(dot_graph) + # t.communicate(dot_graph) if __name__ == '__main__': From b580d92d0d39e6a3fce8daddb37de7cd85213d1e Mon Sep 17 00:00:00 2001 From: Matthew Lee Date: Thu, 5 Mar 2015 15:05:52 -0800 Subject: [PATCH 03/17] Fixed generator and added test. --- bst.py | 3 ++- test_bst.py | 9 +++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/bst.py b/bst.py index 2cdd739..f485d3d 100755 --- a/bst.py +++ b/bst.py @@ -114,7 +114,7 @@ def _get_dot(self, current): def in_order(self, current='dutch'): if current == 'dutch': current = self.top - if current: + if current is not None: for value in self.in_order(self.tree[current].get('left')): yield value yield current @@ -131,6 +131,7 @@ def main(): tree.insert(num) for thing in tree.in_order(): print thing + print tree.tree dot_graph = tree.get_dot() t = subprocess.Popen(["dot", "-Tpng"], stdin=subprocess.PIPE) # t.communicate(dot_graph) diff --git a/test_bst.py b/test_bst.py index 2cadfec..7d4860b 100644 --- a/test_bst.py +++ b/test_bst.py @@ -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 @@ -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)): @@ -75,6 +77,13 @@ def test_contains(filled_tree): assert t.contains(num) is False +def test_in_order(filled_tree): + tree = filled_tree + print tree + for place, item in enumerate(tree.in_order()): + assert place == item + + @pytest.fixture(scope='function') def filled_tree(): tree = bst.Bst() From 971d5e5fe64d64f00d5365d254ef95ea1d8fef67 Mon Sep 17 00:00:00 2001 From: Matthew Lee Date: Thu, 5 Mar 2015 16:03:55 -0800 Subject: [PATCH 04/17] Changed in_order() to reflect nature of the recursive call only yielding one value. --- bst.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/bst.py b/bst.py index f485d3d..d80643b 100755 --- a/bst.py +++ b/bst.py @@ -111,15 +111,13 @@ def _get_dot(self, current): yield "\tnull%s [shape=point];" % r yield "\t%s -> null%s;" % (current, r) - def in_order(self, current='dutch'): - if current == 'dutch': + def in_order(self, current='start'): + if current == 'start': current = self.top if current is not None: - for value in self.in_order(self.tree[current].get('left')): - yield value + self.in_order(self.tree[current].get('left')).next() yield current - for value in self.in_order(self.tree[current].get('right')): - yield value + self.in_order(self.tree[current].get('right')).next() def main(): From 9e87d91fdcb976bb0d7912cfeedaff760ff5de4b Mon Sep 17 00:00:00 2001 From: Henry Grantham Date: Thu, 5 Mar 2015 16:43:54 -0800 Subject: [PATCH 05/17] add breadth first, post_order, and pre_order generators to bst.py and added tests for them --- bst.py | 43 +++++++++++++++++++++++++++++++++++++++++-- test_bst.py | 20 +++++++++++++++++++- 2 files changed, 60 insertions(+), 3 deletions(-) diff --git a/bst.py b/bst.py index f485d3d..044ecba 100755 --- a/bst.py +++ b/bst.py @@ -111,7 +111,9 @@ def _get_dot(self, current): yield "\tnull%s [shape=point];" % r yield "\t%s -> null%s;" % (current, r) + def in_order(self, current='dutch'): + """Generator that traverses the binary tree.""" if current == 'dutch': current = self.top if current is not None: @@ -122,6 +124,43 @@ def in_order(self, current='dutch'): yield value + def pre_order(self, current='dutch'): + """Generator that traverses the binary tree.""" + if current == 'dutch': + current = self.top + if current is not None: + yield current + for value in self.pre_order(self.tree[current].get('left')): + yield value + for value in self.pre_order(self.tree[current].get('right')): + yield value + + + def post_order(self, current='dutch'): + """Generator that traverses the binary tree.""" + if current == 'dutch': + current = self.top + if current is not None: + for value in self.post_order(self.tree[current].get('left')): + yield value + for value in self.post_order(self.tree[current].get('right')): + yield value + yield current + + def breadth_first(self): + """Generator that traverses the binary tree in breadth first order.""" + node_list =[] + node_list.append(self.top) + current = self.top + while node_list: + current = node_list.pop(0) + if self.tree[current].get('left') is not None: + node_list.append(self.tree[current].get('left')) + if self.tree[current].get('right') is not None: + node_list.append(self.tree[current].get('right')) + yield current + + def main(): """Best case and worst case are the same.""" tree = Bst() @@ -129,9 +168,9 @@ def main(): tree.insert(num) for num in range(10, 15): tree.insert(num) - for thing in tree.in_order(): - print thing print tree.tree + for num in enumerate(tree.breadth_first()): + print num dot_graph = tree.get_dot() t = subprocess.Popen(["dot", "-Tpng"], stdin=subprocess.PIPE) # t.communicate(dot_graph) diff --git a/test_bst.py b/test_bst.py index 7d4860b..d2e73ba 100644 --- a/test_bst.py +++ b/test_bst.py @@ -79,11 +79,29 @@ def test_contains(filled_tree): def test_in_order(filled_tree): tree = filled_tree - print tree for place, item in enumerate(tree.in_order()): assert place == item +def test_pre_order(filled_tree): + tree = filled_tree + expected_order = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 10, 11, 12, 13] + for place, item in enumerate(tree.pre_order()): + assert expected_order[place] == item + + +def test_post_order(filled_tree): + tree = filled_tree + expected_order = [0, 1, 2, 3, 4, 5, 6, 7, 8, 13, 12, 11, 10, 9] + for place, item in enumerate(tree.post_order()): + assert expected_order[place] == item + +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(): tree = bst.Bst() From c36afbc60399f18567befa2b4f8f83a19b67a583 Mon Sep 17 00:00:00 2001 From: Matthew Lee Date: Thu, 5 Mar 2015 16:56:53 -0800 Subject: [PATCH 06/17] Fixed unicode decode error. --- linked_list.py | 5 +++-- test_linked_list.py | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/linked_list.py b/linked_list.py index 7458b48..a6bc65c 100644 --- a/linked_list.py +++ b/linked_list.py @@ -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 @@ -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) @@ -113,5 +115,4 @@ def display_prep(self): output = "{}, {}".format(output, dummy) temp = temp.next - return output + ")" diff --git a/test_linked_list.py b/test_linked_list.py index e959241..7728aac 100644 --- a/test_linked_list.py +++ b/test_linked_list.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- # test constructor from linked_list import List_Node from linked_list import Linked_List From 312b764207b457b87906e015c77571907eecb302 Mon Sep 17 00:00:00 2001 From: Matthew Lee Date: Thu, 5 Mar 2015 17:00:52 -0800 Subject: [PATCH 07/17] Added .travis file for this branch. --- .travis.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..bac4e19 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,5 @@ +language: python +python: + - "2.7" +install: "pip install -r requirements.txt" +script: py.test test_graph.py \ No newline at end of file From 2d88e5acff5648564ec318fc0db064589b75ee4a Mon Sep 17 00:00:00 2001 From: Matthew Lee Date: Thu, 5 Mar 2015 17:02:39 -0800 Subject: [PATCH 08/17] Added requirements.txt. --- requirements.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 requirements.txt diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..625ffd1 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +py==1.4.26 +pytest==2.6.4 From 37c5e60a1a476dbb4a44db600b9df20558663cf3 Mon Sep 17 00:00:00 2001 From: Matthew Lee Date: Thu, 5 Mar 2015 17:03:46 -0800 Subject: [PATCH 09/17] Updated .yml file. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index bac4e19..1019a30 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,4 +2,4 @@ language: python python: - "2.7" install: "pip install -r requirements.txt" -script: py.test test_graph.py \ No newline at end of file +script: py.test test_graph.py test_bst.py \ No newline at end of file From 7691f1328700a2944e8bd7f6350b0849d793849d Mon Sep 17 00:00:00 2001 From: Henry Grantham Date: Thu, 5 Mar 2015 17:04:23 -0800 Subject: [PATCH 10/17] updated README.md --- README.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 66d0f71..8f20562 100644 --- a/README.md +++ b/README.md @@ -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. \ No newline at end of file +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) From fd16ce8abfbfd3de0b3b203f06659768f615dfb4 Mon Sep 17 00:00:00 2001 From: Matthew Lee Date: Thu, 5 Mar 2015 17:06:11 -0800 Subject: [PATCH 11/17] Updated to run all tests. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 1019a30..5ca17cf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,4 +2,4 @@ language: python python: - "2.7" install: "pip install -r requirements.txt" -script: py.test test_graph.py test_bst.py \ No newline at end of file +script: py.test \ No newline at end of file From 80f6369a4cb883ee5fcfb787b9214ea62a309c29 Mon Sep 17 00:00:00 2001 From: Matthew Lee Date: Sun, 8 Mar 2015 15:06:17 -0700 Subject: [PATCH 12/17] Changed generators. --- bst.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/bst.py b/bst.py index 204c375..4faf9e6 100755 --- a/bst.py +++ b/bst.py @@ -118,9 +118,11 @@ def in_order(self, current='start'): if current == 'start': current = self.top if current is not None: - self.in_order(self.tree[current].get('left')).next() + for node in self.in_order(self.tree[current].get('left')): + yield node yield current - self.in_order(self.tree[current].get('right')).next() + for node in self.in_order(self.tree[current].get('right')): + yield node def pre_order(self, current='dutch'): """Generator that traverses the binary tree.""" @@ -128,17 +130,21 @@ def pre_order(self, current='dutch'): current = self.top if current is not None: yield current - self.in_order(self.tree[current].get('left')).next() - self.in_order(self.tree[current].get('right')).next() + for node in self.in_order(self.tree[current].get('left')): + yield node + for node in self.in_order(self.tree[current].get('right')): + yield node def post_order(self, current='dutch'): """Generator that traverses the binary tree.""" if current == 'dutch': current = self.top if current is not None: - self.in_order(self.tree[current].get('left')).next() + for node in self.in_order(self.tree[current].get('left')): + yield node self.in_order(self.tree[current].get('right')).next() - yield current + for node in self.in_order(self.tree[current].get('right')): + yield node def breadth_first(self): """Generator that traverses the binary tree in breadth first order.""" From 5e7f8676a65e9939d0bc644298f2d8f6e237e93f Mon Sep 17 00:00:00 2001 From: Henry Grantham Date: Sun, 8 Mar 2015 18:53:06 -0700 Subject: [PATCH 13/17] added helper functions to bst.py to make functions more clear --- bst.py | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/bst.py b/bst.py index 204c375..38964bb 100755 --- a/bst.py +++ b/bst.py @@ -17,6 +17,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') + + def insert(self, value): """Insert a node with value in order. @@ -34,10 +42,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 @@ -118,9 +126,9 @@ def in_order(self, current='start'): if current == 'start': current = self.top if current is not None: - self.in_order(self.tree[current].get('left')).next() + self.in_order(self.left(current)).next() yield current - self.in_order(self.tree[current].get('right')).next() + self.in_order(self.right(current)).next() def pre_order(self, current='dutch'): """Generator that traverses the binary tree.""" @@ -128,16 +136,16 @@ def pre_order(self, current='dutch'): current = self.top if current is not None: yield current - self.in_order(self.tree[current].get('left')).next() - self.in_order(self.tree[current].get('right')).next() + self.in_order(self.left(current)).next() + self.in_order(self.right(current)).next() def post_order(self, current='dutch'): """Generator that traverses the binary tree.""" if current == 'dutch': current = self.top if current is not None: - self.in_order(self.tree[current].get('left')).next() - self.in_order(self.tree[current].get('right')).next() + self.in_order(self.left(current)).next() + self.in_order(self.right(current)).next() yield current def breadth_first(self): @@ -147,10 +155,10 @@ def breadth_first(self): current = self.top while node_list: current = node_list.pop(0) - if self.tree[current].get('left') is not None: - node_list.append(self.tree[current].get('left')) - if self.tree[current].get('right') is not None: - node_list.append(self.tree[current].get('right')) + if self.left(current) is not None: + node_list.append(self.left(current)) + if self.right(current) is not None: + node_list.append(self.right(current)) yield current From aeaba6ebcdb6cb9cf20787ad5da7889822766cf2 Mon Sep 17 00:00:00 2001 From: Henry Grantham Date: Mon, 9 Mar 2015 12:48:46 -0700 Subject: [PATCH 14/17] tests now look at all values in expected case --- test_bst.py | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/test_bst.py b/test_bst.py index d2e73ba..016501d 100644 --- a/test_bst.py +++ b/test_bst.py @@ -79,22 +79,33 @@ def test_contains(filled_tree): def test_in_order(filled_tree): tree = filled_tree - for place, item in enumerate(tree.in_order()): - assert place == item + gen = tree.in_order() + expected_order = range(0, 15) + for i in expected_order: + j = gen.next() + print str(i) + '=' + str(j) + assert i == j 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 place, item in enumerate(tree.pre_order()): - assert expected_order[place] == item + for i in expected_order: + j = gen.next() + print str(i) + '=' + str(j) + assert i == j def test_post_order(filled_tree): tree = filled_tree + gen = tree.pre_order() expected_order = [0, 1, 2, 3, 4, 5, 6, 7, 8, 13, 12, 11, 10, 9] - for place, item in enumerate(tree.post_order()): - assert expected_order[place] == item + for i in expected_order: + j = gen.next() + print str(i) + '=' + str(j) + assert i == j + def test_breadth_first_order(filled_tree): tree = filled_tree From a8c6f85750ceb9495c3b7a5ab2be6e3b8cf1c9c0 Mon Sep 17 00:00:00 2001 From: Henry Grantham Date: Mon, 9 Mar 2015 14:14:38 -0700 Subject: [PATCH 15/17] added a deque to breadth first traverse and fixed in, pre, and post order traversal and fixed the tests --- bst.py | 26 +++++++++++++------------- test_bst.py | 23 ++++++++++++++++++++--- 2 files changed, 33 insertions(+), 16 deletions(-) diff --git a/bst.py b/bst.py index 232da93..bb6d302 100755 --- a/bst.py +++ b/bst.py @@ -1,6 +1,7 @@ #!/usr/bin/env python import random import subprocess +from collections import deque class Bst(object): @@ -157,31 +158,30 @@ def post_order(self, current='dutch'): def breadth_first(self): """Generator that traverses the binary tree in breadth first order.""" - node_list = [] - node_list.append(self.top) + q1 = deque() + q1.appendleft(self.top) current = self.top - while node_list: - current = node_list.pop(0) + while q1: + current = q1.pop() if self.left(current) is not None: - node_list.append(self.left(current)) + q1.appendleft(self.left(current)) if self.right(current) is not None: - node_list.append(self.right(current)) + 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 + # 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) + t.communicate(dot_graph) if __name__ == '__main__': diff --git a/test_bst.py b/test_bst.py index 016501d..d1d546c 100644 --- a/test_bst.py +++ b/test_bst.py @@ -80,11 +80,13 @@ def test_contains(filled_tree): def test_in_order(filled_tree): tree = filled_tree gen = tree.in_order() - expected_order = range(0, 15) + 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): @@ -95,16 +97,19 @@ def test_pre_order(filled_tree): 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.pre_order() + 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): @@ -113,8 +118,10 @@ def test_breadth_first_order(filled_tree): 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) @@ -123,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() From 7ce920e26664735f9dcea81c13841e331e42a65a Mon Sep 17 00:00:00 2001 From: Matthew Lee Date: Mon, 9 Mar 2015 15:04:05 -0700 Subject: [PATCH 16/17] Added reference from children to parents. --- bst.py | 72 +++++++++++++++++++++++++++------------------------------- 1 file changed, 33 insertions(+), 39 deletions(-) diff --git a/bst.py b/bst.py index bb6d302..1b03e3e 100755 --- a/bst.py +++ b/bst.py @@ -1,7 +1,6 @@ #!/usr/bin/env python import random import subprocess -from collections import deque class Bst(object): @@ -18,14 +17,6 @@ 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') - - def insert(self, value): """Insert a node with value in order. @@ -43,15 +34,18 @@ def insert(self, value): if current == value: return if current < value: - traverse = self.right(current) + traverse = self.tree[current].get('right') child = 'right' else: - traverse = self.left(current) + traverse = self.tree[current].get('left') child = 'left' if traverse is None: - #actual insert + # actual insert self.tree[value] = {'depth': depth} self.tree[current][child] = value + # Add reference to parent in new child node information + self.tree[value]['parent'] = current + self._size += 1 if depth > self._depth: self._depth = depth @@ -122,66 +116,66 @@ def _get_dot(self, current): def in_order(self, current='start'): """ - Generator that traverses the binary tree in order. + Generator that traverses the binary tree. """ if current == 'start': current = self.top if current is not None: - for node in self.in_order(self.left(current)): + for node in self.in_order(self.tree[current].get('left')): yield node yield current - for node in self.in_order(self.right(current)): + for node in self.in_order(self.tree[current].get('right')): yield node - def pre_order(self, current='dutch'): - """Generator that traverses the binary tree pre order.""" + """Generator that traverses the binary tree.""" if current == 'dutch': current = self.top if current is not None: yield current - for node in self.pre_order(self.left(current)): + for node in self.in_order(self.tree[current].get('left')): yield node - for node in self.pre_order(self.right(current)): + for node in self.in_order(self.tree[current].get('right')): yield node def post_order(self, current='dutch'): - """Generator that traverses the binary tree post order.""" + """Generator that traverses the binary tree.""" 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)): + for node in self.in_order(self.tree[current].get('left')): yield node - yield current + self.in_order(self.tree[current].get('right')).next() + for node in self.in_order(self.tree[current].get('right')): + yield node def breadth_first(self): """Generator that traverses the binary tree in breadth first order.""" - q1 = deque() - q1.appendleft(self.top) + node_list =[] + node_list.append(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 + while node_list: + current = node_list.pop(0) + if self.tree[current].get('left') is not None: + node_list.append(self.tree[current].get('left')) + if self.tree[current].get('right') is not None: + node_list.append(self.tree[current].get('right')) + yield current def main(): """Best case and worst case are the same.""" tree = Bst() - inserts = [7, 4, 11, 2, 9, 6, 12, 5, 13, 0, 10, 8, 3, 1] - for i in inserts: - tree.insert(i) + for num in reversed(range(10)): + tree.insert(num) + for num in range(10, 15): + tree.insert(num) print tree.tree - # for num in enumerate(tree.pre_order()): - # print num + for num in enumerate(tree.breadth_first()): + print num dot_graph = tree.get_dot() t = subprocess.Popen(["dot", "-Tpng"], stdin=subprocess.PIPE) - t.communicate(dot_graph) + # t.communicate(dot_graph) if __name__ == '__main__': From dbb4e47652913813fe085a3d17240253515e57d3 Mon Sep 17 00:00:00 2001 From: Henry Grantham Date: Mon, 9 Mar 2015 15:11:00 -0700 Subject: [PATCH 17/17] reverted to older commit because lost changes --- bst.py | 72 +++++++++++++++++++++++++++++++--------------------------- 1 file changed, 39 insertions(+), 33 deletions(-) diff --git a/bst.py b/bst.py index 1b03e3e..bb6d302 100755 --- a/bst.py +++ b/bst.py @@ -1,6 +1,7 @@ #!/usr/bin/env python import random import subprocess +from collections import deque class Bst(object): @@ -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') + + def insert(self, value): """Insert a node with value in order. @@ -34,18 +43,15 @@ 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 + #actual insert self.tree[value] = {'depth': depth} self.tree[current][child] = value - # Add reference to parent in new child node information - self.tree[value]['parent'] = current - self._size += 1 if depth > self._depth: self._depth = depth @@ -116,66 +122,66 @@ def _get_dot(self, current): def in_order(self, current='start'): """ - Generator that traverses the binary tree. + Generator that traverses the binary tree in order. """ if current == 'start': current = self.top if current is not None: - for node in self.in_order(self.tree[current].get('left')): + for node in self.in_order(self.left(current)): yield node yield current - for node in self.in_order(self.tree[current].get('right')): + for node in self.in_order(self.right(current)): yield node + def pre_order(self, current='dutch'): - """Generator that traverses the binary tree.""" + """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.in_order(self.tree[current].get('left')): + for node in self.pre_order(self.left(current)): yield node - for node in self.in_order(self.tree[current].get('right')): + for node in self.pre_order(self.right(current)): yield node def post_order(self, current='dutch'): - """Generator that traverses the binary tree.""" + """Generator that traverses the binary tree post order.""" if current == 'dutch': current = self.top if current is not None: - for node in self.in_order(self.tree[current].get('left')): + for node in self.post_order(self.left(current)): + yield node + for node in self.post_order(self.right(current)): yield node - self.in_order(self.tree[current].get('right')).next() - for node in self.in_order(self.tree[current].get('right')): - yield node + yield current def breadth_first(self): """Generator that traverses the binary tree in breadth first order.""" - node_list =[] - node_list.append(self.top) + q1 = deque() + q1.appendleft(self.top) current = self.top - while node_list: - current = node_list.pop(0) - if self.tree[current].get('left') is not None: - node_list.append(self.tree[current].get('left')) - if self.tree[current].get('right') is not None: - node_list.append(self.tree[current].get('right')) - yield current + 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.breadth_first()): - print num + # 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) + t.communicate(dot_graph) if __name__ == '__main__':