From a567898dab4d00acace87aa7341b29bd7a69b8cf Mon Sep 17 00:00:00 2001 From: mag6367 Date: Thu, 16 Jul 2015 10:20:18 -0500 Subject: [PATCH 1/5] new challenge: reverse_words --- arrays_strings/reverse_words/__init__.py | 0 .../reverse_words_challenge.ipynb | 155 +++++++++++++++++ .../reverse_words_solution.ipynb | 162 ++++++++++++++++++ .../reverse_words/reverse_words_solution.py | 16 ++ 4 files changed, 333 insertions(+) create mode 100644 arrays_strings/reverse_words/__init__.py create mode 100644 arrays_strings/reverse_words/reverse_words_challenge.ipynb create mode 100644 arrays_strings/reverse_words/reverse_words_solution.ipynb create mode 100644 arrays_strings/reverse_words/reverse_words_solution.py diff --git a/arrays_strings/reverse_words/__init__.py b/arrays_strings/reverse_words/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/arrays_strings/reverse_words/reverse_words_challenge.ipynb b/arrays_strings/reverse_words/reverse_words_challenge.ipynb new file mode 100644 index 0000000..c51736b --- /dev/null +++ b/arrays_strings/reverse_words/reverse_words_challenge.ipynb @@ -0,0 +1,155 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " This notebook was prepared by Marco Guajardo. For license visit [github](https://github.com/donnemartin/interactive-coding-challenges) \n", + "." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Challenge Notebook\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Problem: Given a string of words, return a string with the words in reverse" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "* [Constraits](#Constraint)\n", + "* [Test Cases](#Test-Cases)\n", + "* [Algorithm](#Algorithm)\n", + "* [Code](#Code)\n", + "* [Unit Test](#Unit-Test)\n", + "* [Solution Notebook](#Solution-Notebook)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Constraints\n", + "* Can we assume the string is ASCII?\n", + " * Yes\n", + "* Is whitespace important?\n", + " * no the whitespace does not change\n", + "* Is this case sensitive?\n", + " * yes\n", + "* What if the string is empty?\n", + " * return None\n", + "* Is the order of words important?\n", + " * yes\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Test Cases\n", + "* Empty string -> None\n", + "* \"the sun is very hot\" -> \"eht nus si yrev toh\"\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Algorithm\n", + "* Refer to the [Solution](https://github.com/donnemartin/interactive-coding-challenges/blob/master/arrays_strings/reverse_words/reverse_words_solution.ipynb) if you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Code " + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def reverse_words (S):\n", + " #TODO: implement me\n", + " pass " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Unit Test\n", + " The following unit test is expected to fail until you solve challenge " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "from nose.tools import assert_equal\n", + "\n", + "class UnitTest (object):\n", + " def testReverseWords(self):\n", + " assert_equal(func('the sun is hot'), 'eht nus si toh')\n", + " assert_equal(func(''), None)\n", + " assert_equal(func('123 456 789'), '321 654 987')\n", + " assert_equal(func('magic'), 'cigam')\n", + " print('Success: reverse_words')\n", + " \n", + "def main():\n", + " test = UnitTest()\n", + " test.testReverseWords()\n", + "\n", + "if __name__==\"__main__\":\n", + " main()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Solution Notebook\n", + "* Review the [Solution Notebook](https://github.com/donnemartin/interactive-coding-challenges/blob/master/arrays_strings/reverse_words/reverse_words_solution.ipynb) for discussion on algorithms and code solutions." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.6" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/arrays_strings/reverse_words/reverse_words_solution.ipynb b/arrays_strings/reverse_words/reverse_words_solution.ipynb new file mode 100644 index 0000000..e7942a1 --- /dev/null +++ b/arrays_strings/reverse_words/reverse_words_solution.ipynb @@ -0,0 +1,162 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " This notebook was prepared by Marco Guajardo. For license visit [github](https://github.com/donnemartin/interactive-coding-challenges) " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Solution notebook\n", + "## Problem: Given a string of words, return a string with the words in reverse" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "* [Constraits](#Constraint)\n", + "* [Test Cases](#Test-Cases)\n", + "* [Algorithm](#Algorithm)\n", + "* [Code](#Code)\n", + "* [Unit Test](#Unit-Test)\n", + "* [Solution Notebook](#Solution-Notebook)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Constraints\n", + "* Can we assume the string is ASCII?\n", + " * Yes\n", + "* Is whitespace important?\n", + " * no the whitespace does not change\n", + "* Is this case sensitive?\n", + " * yes\n", + "* What if the string is empty?\n", + " * return None\n", + "* Is the order of words important?\n", + " * yes\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Algorithm: Split words into a list and reverse each word individually\n", + "Steps:\n", + "\n", + "* Check if string is empty\n", + "* If not empty, split the string into a list of words \n", + "* For each word on the list\n", + " * reverse the word\n", + "* Return the string representation of the list\n", + "\n", + "Complexity:\n", + "\n", + "* Time complexity is O(n) where n is the number of chars.\n", + "* Space complexity is O(n) where n is the number of chars. " + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def reverse_words(S):\n", + " if len(S) is 0:\n", + " return None\n", + " \n", + " words = S.split()\n", + " for i in range (len(words)):\n", + " words[i] = words[i][::-1]\n", + " \n", + " return \" \".join(words)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Overwriting reverse_words_solution.py\n" + ] + } + ], + "source": [ + "%%writefile reverse_words_solution.py\n", + "from nose.tools import assert_equal\n", + "\n", + "class UnitTest (object):\n", + " def testReverseWords(self, func):\n", + " assert_equal(func('the sun is hot'), 'eht nus si toh')\n", + " assert_equal(func(''), None)\n", + " assert_equal(func('123 456 789'), '321 654 987')\n", + " assert_equal(func('magic'), 'cigam')\n", + " print('Success: reverse_words')\n", + " \n", + "def main():\n", + " test = UnitTest()\n", + " test.testReverseWords(reverse_words)\n", + "\n", + "if __name__==\"__main__\":\n", + " main()" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Success: reverse_words\n" + ] + } + ], + "source": [ + "run -i reverse_words_solution.py" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.6" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/arrays_strings/reverse_words/reverse_words_solution.py b/arrays_strings/reverse_words/reverse_words_solution.py new file mode 100644 index 0000000..1e44114 --- /dev/null +++ b/arrays_strings/reverse_words/reverse_words_solution.py @@ -0,0 +1,16 @@ +from nose.tools import assert_equal + +class UnitTest (object): + def testReverseWords(self, func): + assert_equal(func('the sun is hot'), 'eht nus si toh') + assert_equal(func(''), None) + assert_equal(func('123 456 789'), '321 654 987') + assert_equal(func('magic'), 'cigam') + print('Success: reverse_words') + +def main(): + test = UnitTest() + test.testReverseWords(reverse_words) + +if __name__=="__main__": + main() \ No newline at end of file From 5043e791b5386b5f3b60bc289eb472f8545e6175 Mon Sep 17 00:00:00 2001 From: mag6367 Date: Sat, 18 Jul 2015 00:40:13 -0500 Subject: [PATCH 2/5] binary search tree implementation --- graphs_trees/.DS_Store | Bin 0 -> 6148 bytes graphs_trees/__init__.py | 0 graphs_trees/binary_tree/.DS_Store | Bin 0 -> 6148 bytes graphs_trees/binary_tree/__init__.py | 0 .../binary_tree/binary_search_tree.py | 155 ++++++ .../binary_tree/binary_tree_challenge.ipynb | 283 ++++++++++ .../binary_tree/binary_tree_solution.ipynb | 507 ++++++++++++++++++ .../binary_tree/test_binary_search_tree.py | 72 +++ 8 files changed, 1017 insertions(+) create mode 100644 graphs_trees/.DS_Store create mode 100644 graphs_trees/__init__.py create mode 100644 graphs_trees/binary_tree/.DS_Store create mode 100644 graphs_trees/binary_tree/__init__.py create mode 100644 graphs_trees/binary_tree/binary_search_tree.py create mode 100644 graphs_trees/binary_tree/binary_tree_challenge.ipynb create mode 100644 graphs_trees/binary_tree/binary_tree_solution.ipynb create mode 100644 graphs_trees/binary_tree/test_binary_search_tree.py diff --git a/graphs_trees/.DS_Store b/graphs_trees/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..1a99e14e3f083d476e9dcad2515a6ad7ffe1aee2 GIT binary patch literal 6148 zcmeHK&2G~`5S~o~wPgv6)I+)L4GvKi%8!q=LaBtfAh~J}EebZah$YJ#B~GI%MDn2r zXv=#bcoiOiL*FIL>`tndkXwZS?L@QRcs$>(_FKp61pv_*rH=r70C3O=8!k4#F}hE_ zU=7YR5rys}hYGs*+kpN;wN3nu3eehldd+eu;p+Mwzbw?dq)-V~(BrX#{&1!ZBVr|3 zUqTE6IL00-#0;`uSl@|-E@m?#En_9)VV}pkNcu%StlI4#qOsDvb$iuuUC;II-1Xi> zJvEN1xEc*R@!){2UdL50;doc6;xdkty*wLt{k7++tm3@P2AZ6w8I~OG=VhwK9W^S` z;bCNw`*~XRbf=tf9M^HX{`zFH89Z&t&2}(t$w?5jTk=WpY&!K%T<89S$6K!w_2J{E z)3fu>U%u)&g1~=+wtI|o_=dp}-HxI`S*Y?oR?OLRmPM<8Rlq86(+co=#_?{tW80rq zz$)<1D?slDiB1?Y)&}*f0~>t=K%~z|Z5Y$XB5@>R$XFZ1J7~gC5e-%F5knX{<|WsK zjI}{S2f>FA!6OSkp$I)X_Ahlgh|r*ItpZko>k6!xOP}`t7t7E8*GcxuDqt1(uM`l? z?P$A$Q{ugKVRE$BO7yqrWK>rhyrf{Dw_>cNt#}<>8|Ebih#_Nb5Ho1@LqN-58>_${ GRp2K&s&wrD literal 0 HcmV?d00001 diff --git a/graphs_trees/__init__.py b/graphs_trees/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/graphs_trees/binary_tree/.DS_Store b/graphs_trees/binary_tree/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..6abb3368cdbb0ab3e1a79f3f009049d5740454bc GIT binary patch literal 6148 zcmeHKK~BRk5S%SN6mjVV3Be^tPDuP9stOWUctB`M1(Bi#HSM9dJdg+Q8<_Q)iY7$j zgaGYE>#-g0*d9l*4L~NFhf81#U_@6O95VUB^u2n=2C-&Hl)$mV78z#d_MyTB9Q4hGQ(4TXKv&oO0XYTyqRHBeNE}eZAk9y}Y(KS#)y+ zTme_$Pbk1WTWxe?=&38<3b+D01@!-r&=u2&jbZq8FbP)xq8=lIF|P+hjY%S=5gS9k zp^1eOEmYzaLoA&2No!C0SYhL}cd S3|T|-gFukM6Ib9z6?g|h!(F8S literal 0 HcmV?d00001 diff --git a/graphs_trees/binary_tree/__init__.py b/graphs_trees/binary_tree/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/graphs_trees/binary_tree/binary_search_tree.py b/graphs_trees/binary_tree/binary_search_tree.py new file mode 100644 index 0000000..e3b15da --- /dev/null +++ b/graphs_trees/binary_tree/binary_search_tree.py @@ -0,0 +1,155 @@ + +class Node (object): + def __init__ (self, data): + self.data = data + self.rightChild = None + self.leftChild = None + +class BinaryTree (object): + def __init__ (self): + self.root = None + + def insert (self, newData): + leaf = Node(newData) + + if self.root is None: + self.root = leaf + else: + current = self.root + parent = self.root + while current is not None: + parent = current + if newData < current.data: + current = current.leftChild + else: + current = current.rightChild + + if newData < parent.data: + parent.leftChild = leaf + else: + parent.rightChild = leaf + + # returns false if the item to be deleted is not on the tree + def delete (self, data): + current = self.root + parent = self.root + isLeft = False + + if current is None: + return False + + while current is not None and current.data is not data: + parent = current + if data < current.data: + current = current.leftChild + isLeft = True + else: + current = current.rightChild + isLeft = False + + if current is None: + return False + + if current.leftChild is None and current.rightChild is None: + if current is self.root: + self.root = None + elif isLeft: + parent.leftChild = None + else: + parent.rightChild = None + + elif current.rightChild is None: + if current is self.root: + self.root = current.leftChild + elif isLeft: + parent.leftChild = current.leftChild + else: + parent.rightChild = current.leftChild + + elif current.rightChild is None: + if current is self.root: + self.root = current.rightChild + elif isLeft: + parent.lChild = current.rightChild + else: + parent.rightChild = current.rightChild + + else: + succesor = current.rightChild + succesorParent = current + + while succesor.leftChild is not None: + succesorParent = succesor + succesor = succesor.leftChild + + if current is self.root: + self.root = succesor + elif isLeft: + parent.leftChild = succesor + else: + parent.rightChild = succesor + + succesor.leftChild = current.leftChild + + if succesor is not current.rightChild: + succesorParent.leftChild = succesor.rightChild + succesor.rightChild = current.rightChild + + return True + + + def minNode (self): + current = self.root + while current.leftChild is not None: + current = current.leftChild + + return current.data + + def maxNode (self): + current = self.root + while current.rightChild is not None: + current = current.rightChild + + return current.data + + def printPostOrder (self): + global postOrder + postOrder = [] + + def PostOrder(node): + if node is not None: + PostOrder(node.leftChild) + PostOrder(node.rightChild) + postOrder.append(node.data) + + PostOrder(self.root) + return postOrder + + def printInOrder (self): + global inOrder + inOrder = [] + + def InOrder (node): + if node is not None: + InOrder(node.leftChild) + inOrder.append(node.data) + InOrder(node.rightChild) + + InOrder(self.root) + return inOrder + + def printPreOrder (self): + global preOrder + preOrder = [] + + def PreOrder (node): + if node is not None: + preOrder.append(node.data) + PreOrder(node.leftChild) + PreOrder(node.rightChild) + + PreOrder(self.root) + return preOrder + + def treeIsEmpty (self): + return self.root is None \ No newline at end of file diff --git a/graphs_trees/binary_tree/binary_tree_challenge.ipynb b/graphs_trees/binary_tree/binary_tree_challenge.ipynb new file mode 100644 index 0000000..bfb91c1 --- /dev/null +++ b/graphs_trees/binary_tree/binary_tree_challenge.ipynb @@ -0,0 +1,283 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This notebook was prepared by Marco Guajardo. Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Challenge Notebook" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Problem: Implement a binary search tree with insert, delete, different traversals & max/min node values\n", + "* [Constraints](#Constraints)\n", + "* [Test Cases](#Test-Cases)\n", + "* [Algorithm](#Algorithm)\n", + "* [Code](#Code)\n", + "* [Unit Test](#Unit-Test)\n", + "* [Solution Notebook](#Solution-Notebook)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Constraints\n", + "* Is this a binary tree?\n", + " * Yes\n", + "* Is the root set to None initially?\n", + " * Yes\n", + "* Do we care if the tree is balanced?\n", + " * No\n", + "* What do we return for the traversals?\n", + " * Return a list of the data in the desired order\n", + "* What type of data can the tree hold?\n", + " * Assume the tree only takes ints. In a realistic example, we'd use a hash table to convert other types to ints." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Test Cases\n", + "\n", + "### Insert \n", + "\n", + "* Always start with the root\n", + "* If value is less than the root, go to the left child\n", + "* if value is more than the root, go to the right child\n", + "\n", + "\n", + "### Delete\n", + "\n", + "* Deleting a node from a binary tree is tricky. Make sure you arrange the tree correctly when deleting a node.\n", + "* Here are some basic [instructions](http://www.algolist.net/Data_structures/Binary_search_tree/Removal)\n", + "* If the value to delete isn't on the tree return False\n", + "\n", + "### Traverals \n", + "\n", + "* In order traversal -left, center, right\n", + "* Pre order traversal - center, left, right\n", + "* Post order traversal - left, right, center\n", + "* Return list for all traverals \n", + "\n", + "### Max & Min\n", + "* Find the max node in the binary search tree\n", + "* Find the min node in the binary search tree\n", + "\n", + "### treeIsEmpty\n", + "* check if the tree is empty\n", + "\n", + "\n", + "## Algorithm\n", + "\n", + "Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/binary_tree_implementation/binary_tree_solution.ipynb). If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Code" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "class Node (object):\n", + " def __init__ (self, data=None):\n", + " #TODO:implement me\n", + " pass\n", + " \n", + " def __str__ (self):\n", + " #TODO:implement me\n", + " pass" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "class BinaryTree (object):\n", + " def __init__ (self):\n", + " #TODO:implement me\n", + " pass\n", + " \n", + " def insert (self, newData):\n", + " #TODO:implement me\n", + " pass\n", + " \n", + " def delete (self, key):\n", + " #TODO:implement me\n", + " pass\n", + " \n", + " def maxNode (self):\n", + " #TODO:implement me\n", + " pass\n", + " \n", + " def minNode (self):\n", + " #TODO:implement me\n", + " pass\n", + " \n", + " def printPostOrder (self):\n", + " #TODO:implement me\n", + " pass\n", + " \n", + " def printPreOrder (self):\n", + " #TODO:implement me\n", + " pass\n", + " \n", + " def printInOrder (self):\n", + " #TODO:implement me\n", + " pass\n", + " \n", + " def treeIsEmpty (self):\n", + " #TODO: implement me\n", + " pass\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Unit Test" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**The following unit test is expected to fail until you solve the challenge.**" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "from nose.tools import assert_equal\n", + "\n", + "class TestBinaryTree(object):\n", + "\n", + "\tdef test_insert_traversals (self):\n", + "\t\tmyTree = BinaryTree()\n", + "\t\tmyTree2 = BinaryTree()\n", + "\t\tfor num in [50, 30, 70, 10, 40, 60, 80, 7, 25, 38]:\n", + "\t\t\tmyTree.insert(num)\n", + "\t\t[myTree2.insert(num) for num in range (1, 100, 10)]\n", + "\n", + "\t\tprint(\"Test: insert checking with in order traversal\")\n", + "\t\tassert_equal(myTree.printInOrder(), [7, 10, 25, 30, 38, 40, 50, 60, 70, 80])\n", + "\t\tassert_equal(myTree2.printInOrder(), [1, 11, 21, 31, 41, 51, 61, 71, 81, 91])\n", + "\t\tprint(\"Test: insert checking with post order traversal\")\n", + "\t\tassert_equal(myTree.printPostOrder(), [7, 25, 10, 38, 40, 30, 60, 80, 70, 50])\n", + "\t\tassert_equal(myTree2.printPostOrder(), [91, 81, 71, 61, 51, 41, 31, 21, 11, 1])\n", + "\n", + "\n", + "\t\tprint(\"Test: insert checking with pre order traversal\")\n", + "\t\tassert_equal(myTree.printPreOrder(), [50, 30, 10, 7, 25, 40, 38, 70, 60, 80])\n", + "\t\tassert_equal(myTree2.printPreOrder(), [1, 11, 21, 31, 41, 51, 61, 71, 81, 91])\n", + "\n", + "\n", + "\t\tprint(\"Success: test_insert_traversals\")\n", + "\n", + "\tdef test_max_min_nodes (self):\n", + "\t\tmyTree = BinaryTree()\n", + "\t\tmyTree.insert(5)\n", + "\t\tmyTree.insert(1)\n", + "\t\tmyTree.insert(21)\n", + "\n", + "\t\tprint(\"Test: max node\")\n", + "\t\tassert_equal(myTree.maxNode(), 21)\n", + "\t\tmyTree.insert(32)\n", + "\t\tassert_equal(myTree.maxNode(), 32)\n", + "\n", + "\t\tprint(\"Test: min node\")\n", + "\t\tassert_equal(myTree.minNode(), 1)\n", + "\n", + "\t\tprint(\"Test: min node inserting negative number\")\n", + "\t\tmyTree.insert(-10)\n", + "\t\tassert_equal(myTree.minNode(), -10)\n", + "\n", + "\t\tprint(\"Success: test_max_min_nodes\")\n", + "\n", + "\tdef test_delete (self):\n", + "\t\tmyTree = BinaryTree()\n", + "\t\tmyTree.insert(5)\n", + "\n", + "\t\tprint(\"Test: delete\")\n", + "\t\tmyTree.delete(5)\n", + "\t\tassert_equal(myTree.treeIsEmpty(), True)\n", + "\t\t\n", + "\t\tprint(\"Test: more complex deletions\")\n", + "\t\t[myTree.insert(x) for x in range(1, 5)]\n", + "\t\tmyTree.delete(2)\n", + "\t\tassert_equal(myTree.root.rightChild.data, 3)\n", + "\n", + "\n", + "\t\tprint(\"Success: test_delete\")\n", + "\n", + "def main():\n", + " testing = TestBinaryTree()\n", + " testing.test_insert_traversals()\n", + " testing.test_max_min_nodes()\n", + " testing.test_delete()\n", + " \n", + "if __name__=='__main__':\n", + " main()\n", + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Solution NoteBook\n", + "\n", + "Review the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/binary_tree_implementation/binary_tree_solution.ipynb) for a discussion on algorithms and code solutions." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.4.3" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/graphs_trees/binary_tree/binary_tree_solution.ipynb b/graphs_trees/binary_tree/binary_tree_solution.ipynb new file mode 100644 index 0000000..68eb565 --- /dev/null +++ b/graphs_trees/binary_tree/binary_tree_solution.ipynb @@ -0,0 +1,507 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This notebook was prepared by Marco Guajardo. Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Solution Notebook" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Problem: Implement a binary search tree with insert, delete, different traversals & max/min node values\n", + "* [Constraints](#Constraints)\n", + "* [Test Cases](#Test-Cases)\n", + "* [Algorithm](#Algorithm)\n", + "* [Code](#Code)\n", + "* [Unit Test](#Unit-Test)\n", + "* [Solution Notebook](#Solution-Notebook)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Constraints\n", + "* Is this a binary tree?\n", + " * Yes\n", + "* Is the root set to None initially?\n", + " * Yes\n", + "* Do we care if the tree is balanced?\n", + " * No\n", + "* What do we return for the traversals?\n", + " * Return a list of the data in the desired order\n", + "* What type of data can the tree hold?\n", + " * Assume the tree only takes ints. In a realistic example, we'd use a hash table to convert other types to ints." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Test Cases\n", + "\n", + "### Insert \n", + "\n", + "* Always start with the root\n", + "* If value is less than the root, go to the left child\n", + "* if value is more than the root, go to the right child\n", + "\n", + "\n", + "### Delete\n", + "\n", + "* Deleting a node from a binary tree is tricky. Make sure you arrange the tree correctly when deleting a node.\n", + "* Here are some basic [instructions](http://www.algolist.net/Data_structures/Binary_search_tree/Removal)\n", + "* If the value to delete isn't on the tree return False\n", + "\n", + "\n", + "### Traverals \n", + "\n", + "* In order traversal -left, center, right\n", + "* Pre order traversal - center, left, right\n", + "* Post order traversal - left, right, center\n", + "* Return list for all traverals \n", + "\n", + "### Max & Min\n", + "* Find the max node in the binary search tree\n", + "* Find the min node in the binary search tree\n", + "\n", + "### treeIsEmpty\n", + "* check if the tree is empty\n", + "\n", + "\n", + "## Algorithm\n", + "\n", + "Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/binary_tree_implementation/binary_tree_solution.ipynb). If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Algorithm\n", + "\n", + "### Insert\n", + "\n", + "* If root is none, insert at root\n", + "* Else\n", + " * While node is not None\n", + " * if value is less go left child\n", + " * If value is more go right child\n", + "\n", + "\n", + "* Time complexity: O(log(n))\n", + "* Space complexity: O(n)\n", + "\n", + "### Min Node\n", + "\n", + "* Keep going to the left child until you reach None and return the value\n", + "\n", + "\n", + "* Time complexity: O(log(n))\n", + "* Space complexity: O(n)\n", + "\n", + "### Max Node\n", + "\n", + "* Keep going to the right child until you reach None and return the value\n", + "\n", + "\n", + "* Time complexity: O(log(n))\n", + "* Space complexity: O(n)\n", + "\n", + "### Traversals\n", + "\n", + "* In order\n", + " * While the node is not None\n", + " * Call left child recursively\n", + " * Append data\n", + " * Call right child recursively \n", + " \n", + "* Post order\n", + " * While the node is not None\n", + " * Call left child recursively\n", + " * Call right child recursively \n", + " * Append data\n", + " \n", + "* Pre order\n", + " * While the node is not None\n", + " * Append data\n", + " * Call left child recursively\n", + " * Call right child recursively \n", + "\n", + "\n", + "* Time complexity: O(n) for all traversals\n", + "* Space complexity: O(n)\n", + "\n", + "### Delete\n", + "\n", + "* First, find value to delete\n", + "* If value is not in tree \n", + " * Return False\n", + "* If value found\n", + " * Check if the node is a left child or right child\n", + " * If node is left child\n", + " * Find the biggest value in all the node's children and replace it with it\n", + " * If node is right child\n", + " * Find the smalles value in all the node's children and replace it with it\n", + "\n", + "\n", + "* Time complexity: O(log(n))\n", + "* Space complexity: O(n)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Code" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Overwriting binary_search_tree.py\n" + ] + } + ], + "source": [ + "%%writefile binary_search_tree.py\n", + "\n", + "class Node (object):\n", + "\tdef __init__ (self, data):\n", + "\t\tself.data = data\n", + "\t\tself.rightChild = None\n", + "\t\tself.leftChild = None\n", + "\n", + "class BinaryTree (object):\n", + "\tdef __init__ (self):\n", + "\t\tself.root = None\n", + "\n", + "\tdef insert (self, newData):\n", + "\t\tleaf = Node(newData)\n", + "\n", + "\t\tif self.root is None:\n", + "\t\t\tself.root = leaf\n", + "\t\telse:\n", + "\t\t\tcurrent = self.root\n", + "\t\t\tparent = self.root\n", + "\t\t\twhile current is not None:\n", + "\t\t\t\tparent = current\n", + "\t\t\t\tif newData < current.data:\n", + "\t\t\t\t\tcurrent = current.leftChild\n", + "\t\t\t\telse:\n", + "\t\t\t\t\tcurrent = current.rightChild\n", + "\n", + "\t\t\tif newData < parent.data:\n", + "\t\t\t\tparent.leftChild = leaf\n", + "\t\t\telse:\n", + "\t\t\t\tparent.rightChild = leaf\n", + "\n", + "\t# returns false if the item to be deleted is not on the tree\n", + "\tdef delete (self, data):\n", + "\t\tcurrent = self.root\n", + "\t\tparent = self.root\n", + "\t\tisLeft = False\n", + "\n", + "\t\tif current is None:\n", + "\t\t\treturn False\n", + "\n", + "\t\twhile current is not None and current.data is not data:\n", + "\t\t\tparent = current\n", + "\t\t\tif data < current.data:\n", + "\t\t\t\tcurrent = current.leftChild\n", + "\t\t\t\tisLeft = True \n", + "\t\t\telse:\n", + "\t\t\t\tcurrent = current.rightChild\n", + "\t\t\t\tisLeft = False\n", + "\n", + "\t\tif current is None:\n", + "\t\t\treturn False\n", + "\n", + "\t\tif current.leftChild is None and current.rightChild is None:\n", + "\t\t\tif current is self.root:\n", + "\t\t\t\tself.root = None\n", + "\t\t\telif isLeft:\n", + "\t\t\t\tparent.leftChild = None\n", + "\t\t\telse:\n", + "\t\t\t\tparent.rightChild = None\n", + "\n", + "\t\telif current.rightChild is None:\n", + "\t\t\tif current is self.root:\n", + "\t\t\t\tself.root = current.leftChild\n", + "\t\t\telif isLeft:\n", + "\t\t\t\tparent.leftChild = current.leftChild\n", + "\t\t\telse:\n", + "\t\t\t\tparent.rightChild = current.leftChild\n", + "\n", + "\t\telif current.rightChild is None:\n", + "\t\t\tif current is self.root:\n", + "\t\t\t\tself.root = current.rightChild\n", + "\t\t\telif isLeft:\n", + "\t\t\t\tparent.lChild = current.rightChild\n", + "\t\t\telse:\n", + "\t\t\t\tparent.rightChild = current.rightChild\n", + "\n", + "\t\telse:\n", + "\t\t\tsuccesor = current.rightChild\n", + "\t\t\tsuccesorParent = current\n", + "\n", + "\t\t\twhile succesor.leftChild is not None:\n", + "\t\t\t\tsuccesorParent = succesor\n", + "\t\t\t\tsuccesor = succesor.leftChild\n", + "\n", + "\t\t\tif current is self.root:\n", + "\t\t\t\tself.root = succesor\n", + "\t\t\telif isLeft:\n", + "\t\t\t\tparent.leftChild = succesor\n", + "\t\t\telse:\n", + "\t\t\t\tparent.rightChild = succesor\n", + "\n", + "\t\t\tsuccesor.leftChild = current.leftChild\n", + "\n", + "\t\t\tif succesor is not current.rightChild:\n", + "\t\t\t\tsuccesorParent.leftChild = succesor.rightChild\n", + "\t\t\t\tsuccesor.rightChild = current.rightChild\n", + "\n", + "\t\treturn True \n", + "\n", + "\n", + "\tdef minNode (self):\n", + "\t\tcurrent = self.root\n", + "\t\twhile current.leftChild is not None:\n", + "\t\t\tcurrent = current.leftChild\n", + "\n", + "\t\treturn current.data\n", + "\n", + "\tdef maxNode (self):\n", + "\t\tcurrent = self.root\n", + "\t\twhile current.rightChild is not None:\n", + "\t\t\tcurrent = current.rightChild\n", + "\n", + "\t\treturn current.data\n", + "\n", + "\tdef printPostOrder (self):\n", + "\t\tglobal postOrder\n", + "\t\tpostOrder = []\n", + "\n", + "\t\tdef PostOrder(node):\n", + "\t\t\tif node is not None:\n", + "\t\t\t\tPostOrder(node.leftChild)\n", + "\t\t\t\tPostOrder(node.rightChild)\n", + "\t\t\t\tpostOrder.append(node.data)\n", + "\n", + "\t\tPostOrder(self.root)\n", + "\t\treturn postOrder\n", + "\n", + "\tdef printInOrder (self):\n", + "\t\tglobal inOrder \n", + "\t\tinOrder = []\n", + "\n", + "\t\tdef InOrder (node):\n", + "\t\t\tif node is not None:\n", + "\t\t\t\tInOrder(node.leftChild)\n", + "\t\t\t\tinOrder.append(node.data)\n", + "\t\t\t\tInOrder(node.rightChild)\n", + "\n", + "\t\tInOrder(self.root)\n", + "\t\treturn inOrder\n", + "\n", + "\tdef printPreOrder (self):\n", + "\t\tglobal preOrder\n", + "\t\tpreOrder = []\n", + "\n", + "\t\tdef PreOrder (node):\n", + "\t\t\tif node is not None:\n", + "\t\t\t\tpreOrder.append(node.data)\n", + "\t\t\t\tPreOrder(node.leftChild)\n", + "\t\t\t\tPreOrder(node.rightChild)\n", + "\n", + "\t\tPreOrder(self.root)\n", + "\t\treturn preOrder\n", + "\n", + "\tdef treeIsEmpty (self):\n", + "\t\treturn self.root is None" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%run binary_search_tree.py" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Overwriting test_binary_search_tree.py\n" + ] + } + ], + "source": [ + "%%writefile test_binary_search_tree.py\n", + "from nose.tools import assert_equal\n", + "\n", + "class TestBinaryTree(BinaryTree):\n", + "\n", + "\tdef test_insert_traversals (self):\n", + "\t\tmyTree = BinaryTree()\n", + "\t\tmyTree2 = BinaryTree()\n", + "\t\tfor num in [50, 30, 70, 10, 40, 60, 80, 7, 25, 38]:\n", + "\t\t\tmyTree.insert(num)\n", + "\t\t[myTree2.insert(num) for num in range (1, 100, 10)]\n", + "\n", + "\t\tprint(\"Test: insert checking with in order traversal\")\n", + "\t\tassert_equal(myTree.printInOrder(), [7, 10, 25, 30, 38, 40, 50, 60, 70, 80])\n", + "\t\tassert_equal(myTree2.printInOrder(), [1, 11, 21, 31, 41, 51, 61, 71, 81, 91])\n", + "\t\tprint(\"Test: insert checking with post order traversal\")\n", + "\t\tassert_equal(myTree.printPostOrder(), [7, 25, 10, 38, 40, 30, 60, 80, 70, 50])\n", + "\t\tassert_equal(myTree2.printPostOrder(), [91, 81, 71, 61, 51, 41, 31, 21, 11, 1])\n", + "\n", + "\n", + "\t\tprint(\"Test: insert checking with pre order traversal\")\n", + "\t\tassert_equal(myTree.printPreOrder(), [50, 30, 10, 7, 25, 40, 38, 70, 60, 80])\n", + "\t\tassert_equal(myTree2.printPreOrder(), [1, 11, 21, 31, 41, 51, 61, 71, 81, 91])\n", + "\n", + "\n", + "\t\tprint(\"Success: test_insert_traversals\")\n", + "\n", + "\tdef test_max_min_nodes (self):\n", + "\t\tmyTree = BinaryTree()\n", + "\t\tmyTree.insert(5)\n", + "\t\tmyTree.insert(1)\n", + "\t\tmyTree.insert(21)\n", + "\n", + "\t\tprint(\"Test: max node\")\n", + "\t\tassert_equal(myTree.maxNode(), 21)\n", + "\t\tmyTree.insert(32)\n", + "\t\tassert_equal(myTree.maxNode(), 32)\n", + "\n", + "\t\tprint(\"Test: min node\")\n", + "\t\tassert_equal(myTree.minNode(), 1)\n", + "\n", + "\t\tprint(\"Test: min node inserting negative number\")\n", + "\t\tmyTree.insert(-10)\n", + "\t\tassert_equal(myTree.minNode(), -10)\n", + "\n", + "\t\tprint(\"Success: test_max_min_nodes\")\n", + "\n", + "\tdef test_delete (self):\n", + "\t\tmyTree = BinaryTree()\n", + "\t\tmyTree.insert(5)\n", + "\n", + "\t\tprint(\"Test: delete\")\n", + "\t\tmyTree.delete(5)\n", + "\t\tassert_equal(myTree.treeIsEmpty(), True)\n", + "\t\t\n", + "\t\tprint(\"Test: more complex deletions\")\n", + "\t\t[myTree.insert(x) for x in range(1, 5)]\n", + "\t\tmyTree.delete(2)\n", + "\t\tassert_equal(myTree.root.rightChild.data, 3)\n", + "\t\tprint(\"Test: delete invalid value\")\n", + "\t\tassert_equal(myTree.delete(100), False)\n", + "\n", + "\n", + "\t\tprint(\"Success: test_delete\")\n", + "\n", + "def main():\n", + " testing = TestBinaryTree()\n", + " testing.test_insert_traversals()\n", + " testing.test_max_min_nodes()\n", + " testing.test_delete()\n", + " \n", + "if __name__=='__main__':\n", + " main()" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Test: insert checking with in order traversal\n", + "Test: insert checking with post order traversal\n", + "Test: insert checking with pre order traversal\n", + "Success: test_insert_traversals\n", + "Test: max node\n", + "Test: min node\n", + "Test: min node inserting negative number\n", + "Success: test_max_min_nodes\n", + "Test: delete\n", + "Test: more complex deletions\n", + "Test: delete invalid value\n", + "Success: test_delete\n" + ] + } + ], + "source": [ + "%run -i test_binary_search_tree.py" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.4.3" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/graphs_trees/binary_tree/test_binary_search_tree.py b/graphs_trees/binary_tree/test_binary_search_tree.py new file mode 100644 index 0000000..0b72f8b --- /dev/null +++ b/graphs_trees/binary_tree/test_binary_search_tree.py @@ -0,0 +1,72 @@ +from nose.tools import assert_equal + +class TestBinaryTree(BinaryTree): + + def test_insert_traversals (self): + myTree = BinaryTree() + myTree2 = BinaryTree() + for num in [50, 30, 70, 10, 40, 60, 80, 7, 25, 38]: + myTree.insert(num) + [myTree2.insert(num) for num in range (1, 100, 10)] + + print("Test: insert checking with in order traversal") + assert_equal(myTree.printInOrder(), [7, 10, 25, 30, 38, 40, 50, 60, 70, 80]) + assert_equal(myTree2.printInOrder(), [1, 11, 21, 31, 41, 51, 61, 71, 81, 91]) + print("Test: insert checking with post order traversal") + assert_equal(myTree.printPostOrder(), [7, 25, 10, 38, 40, 30, 60, 80, 70, 50]) + assert_equal(myTree2.printPostOrder(), [91, 81, 71, 61, 51, 41, 31, 21, 11, 1]) + + + print("Test: insert checking with pre order traversal") + assert_equal(myTree.printPreOrder(), [50, 30, 10, 7, 25, 40, 38, 70, 60, 80]) + assert_equal(myTree2.printPreOrder(), [1, 11, 21, 31, 41, 51, 61, 71, 81, 91]) + + + print("Success: test_insert_traversals") + + def test_max_min_nodes (self): + myTree = BinaryTree() + myTree.insert(5) + myTree.insert(1) + myTree.insert(21) + + print("Test: max node") + assert_equal(myTree.maxNode(), 21) + myTree.insert(32) + assert_equal(myTree.maxNode(), 32) + + print("Test: min node") + assert_equal(myTree.minNode(), 1) + + print("Test: min node inserting negative number") + myTree.insert(-10) + assert_equal(myTree.minNode(), -10) + + print("Success: test_max_min_nodes") + + def test_delete (self): + myTree = BinaryTree() + myTree.insert(5) + + print("Test: delete") + myTree.delete(5) + assert_equal(myTree.treeIsEmpty(), True) + + print("Test: more complex deletions") + [myTree.insert(x) for x in range(1, 5)] + myTree.delete(2) + assert_equal(myTree.root.rightChild.data, 3) + print("Test: delete invalid value") + assert_equal(myTree.delete(100), False) + + + print("Success: test_delete") + +def main(): + testing = TestBinaryTree() + testing.test_insert_traversals() + testing.test_max_min_nodes() + testing.test_delete() + +if __name__=='__main__': + main() \ No newline at end of file From f8bccf47aaf3df83909d72588e20fd02131b4831 Mon Sep 17 00:00:00 2001 From: Marco Date: Sat, 18 Jul 2015 00:40:46 -0500 Subject: [PATCH 3/5] Delete .DS_Store --- graphs_trees/binary_tree/.DS_Store | Bin 6148 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 graphs_trees/binary_tree/.DS_Store diff --git a/graphs_trees/binary_tree/.DS_Store b/graphs_trees/binary_tree/.DS_Store deleted file mode 100644 index 6abb3368cdbb0ab3e1a79f3f009049d5740454bc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHKK~BRk5S%SN6mjVV3Be^tPDuP9stOWUctB`M1(Bi#HSM9dJdg+Q8<_Q)iY7$j zgaGYE>#-g0*d9l*4L~NFhf81#U_@6O95VUB^u2n=2C-&Hl)$mV78z#d_MyTB9Q4hGQ(4TXKv&oO0XYTyqRHBeNE}eZAk9y}Y(KS#)y+ zTme_$Pbk1WTWxe?=&38<3b+D01@!-r&=u2&jbZq8FbP)xq8=lIF|P+hjY%S=5gS9k zp^1eOEmYzaLoA&2No!C0SYhL}cd S3|T|-gFukM6Ib9z6?g|h!(F8S From 2576e5cdba7a2446e1330da6f54fbfee5ba6bb14 Mon Sep 17 00:00:00 2001 From: Marco Date: Sat, 18 Jul 2015 00:41:25 -0500 Subject: [PATCH 4/5] Delete .DS_Store --- graphs_trees/.DS_Store | Bin 6148 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 graphs_trees/.DS_Store diff --git a/graphs_trees/.DS_Store b/graphs_trees/.DS_Store deleted file mode 100644 index 1a99e14e3f083d476e9dcad2515a6ad7ffe1aee2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHK&2G~`5S~o~wPgv6)I+)L4GvKi%8!q=LaBtfAh~J}EebZah$YJ#B~GI%MDn2r zXv=#bcoiOiL*FIL>`tndkXwZS?L@QRcs$>(_FKp61pv_*rH=r70C3O=8!k4#F}hE_ zU=7YR5rys}hYGs*+kpN;wN3nu3eehldd+eu;p+Mwzbw?dq)-V~(BrX#{&1!ZBVr|3 zUqTE6IL00-#0;`uSl@|-E@m?#En_9)VV}pkNcu%StlI4#qOsDvb$iuuUC;II-1Xi> zJvEN1xEc*R@!){2UdL50;doc6;xdkty*wLt{k7++tm3@P2AZ6w8I~OG=VhwK9W^S` z;bCNw`*~XRbf=tf9M^HX{`zFH89Z&t&2}(t$w?5jTk=WpY&!K%T<89S$6K!w_2J{E z)3fu>U%u)&g1~=+wtI|o_=dp}-HxI`S*Y?oR?OLRmPM<8Rlq86(+co=#_?{tW80rq zz$)<1D?slDiB1?Y)&}*f0~>t=K%~z|Z5Y$XB5@>R$XFZ1J7~gC5e-%F5knX{<|WsK zjI}{S2f>FA!6OSkp$I)X_Ahlgh|r*ItpZko>k6!xOP}`t7t7E8*GcxuDqt1(uM`l? z?P$A$Q{ugKVRE$BO7yqrWK>rhyrf{Dw_>cNt#}<>8|Ebih#_Nb5Ho1@LqN-58>_${ GRp2K&s&wrD From 980eabae6807d182a5fcfd709274e1adfb7e5f8d Mon Sep 17 00:00:00 2001 From: mag6367 Date: Sat, 18 Jul 2015 00:55:33 -0500 Subject: [PATCH 5/5] binary tree implementation --- .../binary_tree/binary_tree_challenge.ipynb | 41 +++++++++++-------- .../binary_tree/binary_tree_solution.ipynb | 39 +++++++++--------- .../binary_tree/test_binary_search_tree.py | 21 ++++++---- 3 files changed, 58 insertions(+), 43 deletions(-) diff --git a/graphs_trees/binary_tree/binary_tree_challenge.ipynb b/graphs_trees/binary_tree/binary_tree_challenge.ipynb index bfb91c1..4af5494 100644 --- a/graphs_trees/binary_tree/binary_tree_challenge.ipynb +++ b/graphs_trees/binary_tree/binary_tree_challenge.ipynb @@ -161,16 +161,9 @@ "## Unit Test" ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**The following unit test is expected to fail until you solve the challenge.**" - ] - }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 6, "metadata": { "collapsed": false }, @@ -188,16 +181,23 @@ "\t\t[myTree2.insert(num) for num in range (1, 100, 10)]\n", "\n", "\t\tprint(\"Test: insert checking with in order traversal\")\n", - "\t\tassert_equal(myTree.printInOrder(), [7, 10, 25, 30, 38, 40, 50, 60, 70, 80])\n", - "\t\tassert_equal(myTree2.printInOrder(), [1, 11, 21, 31, 41, 51, 61, 71, 81, 91])\n", + "\t\texpectVal = [7, 10, 25, 30, 38, 40, 50, 60, 70, 80]\n", + "\t\tassert_equal(myTree.printInOrder(), expectVal)\n", + "\t\texpectVal = [1, 11, 21, 31, 41, 51, 61, 71, 81, 91]\n", + "\t\tassert_equal(myTree2.printInOrder(), expectVal)\n", + "\n", "\t\tprint(\"Test: insert checking with post order traversal\")\n", - "\t\tassert_equal(myTree.printPostOrder(), [7, 25, 10, 38, 40, 30, 60, 80, 70, 50])\n", - "\t\tassert_equal(myTree2.printPostOrder(), [91, 81, 71, 61, 51, 41, 31, 21, 11, 1])\n", + "\t\texpectVal = [7, 25, 10, 38, 40, 30, 60, 80, 70, 50]\n", + "\t\tassert_equal(myTree.printPostOrder(), expectVal)\n", + "\t\texpectVal = [91, 81, 71, 61, 51, 41, 31, 21, 11, 1]\n", + "\t\tassert_equal(myTree2.printPostOrder(), expectVal)\n", "\n", "\n", "\t\tprint(\"Test: insert checking with pre order traversal\")\n", - "\t\tassert_equal(myTree.printPreOrder(), [50, 30, 10, 7, 25, 40, 38, 70, 60, 80])\n", - "\t\tassert_equal(myTree2.printPreOrder(), [1, 11, 21, 31, 41, 51, 61, 71, 81, 91])\n", + "\t\texpectVal = [50, 30, 10, 7, 25, 40, 38, 70, 60, 80]\n", + "\t\tassert_equal(myTree.printPreOrder(), expectVal)\n", + "\t\texpectVal = [1, 11, 21, 31, 41, 51, 61, 71, 81, 91]\n", + "\t\tassert_equal(myTree2.printPreOrder(), expectVal)\n", "\n", "\n", "\t\tprint(\"Success: test_insert_traversals\")\n", @@ -234,6 +234,9 @@ "\t\t[myTree.insert(x) for x in range(1, 5)]\n", "\t\tmyTree.delete(2)\n", "\t\tassert_equal(myTree.root.rightChild.data, 3)\n", + " \n", + "\t\tprint(\"Test: delete invalid value\")\n", + "\t\tassert_equal(myTree.delete(100), False)\n", "\n", "\n", "\t\tprint(\"Success: test_delete\")\n", @@ -245,8 +248,14 @@ " testing.test_delete()\n", " \n", "if __name__=='__main__':\n", - " main()\n", - " " + " main()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**The following unit test is expected to fail until you solve the challenge.**" ] }, { diff --git a/graphs_trees/binary_tree/binary_tree_solution.ipynb b/graphs_trees/binary_tree/binary_tree_solution.ipynb index 68eb565..7917952 100644 --- a/graphs_trees/binary_tree/binary_tree_solution.ipynb +++ b/graphs_trees/binary_tree/binary_tree_solution.ipynb @@ -169,7 +169,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 7, "metadata": { "collapsed": false }, @@ -343,7 +343,7 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": 8, "metadata": { "collapsed": false }, @@ -354,7 +354,7 @@ }, { "cell_type": "code", - "execution_count": 36, + "execution_count": 9, "metadata": { "collapsed": false }, @@ -371,7 +371,7 @@ "%%writefile test_binary_search_tree.py\n", "from nose.tools import assert_equal\n", "\n", - "class TestBinaryTree(BinaryTree):\n", + "class TestBinaryTree(object):\n", "\n", "\tdef test_insert_traversals (self):\n", "\t\tmyTree = BinaryTree()\n", @@ -381,16 +381,23 @@ "\t\t[myTree2.insert(num) for num in range (1, 100, 10)]\n", "\n", "\t\tprint(\"Test: insert checking with in order traversal\")\n", - "\t\tassert_equal(myTree.printInOrder(), [7, 10, 25, 30, 38, 40, 50, 60, 70, 80])\n", - "\t\tassert_equal(myTree2.printInOrder(), [1, 11, 21, 31, 41, 51, 61, 71, 81, 91])\n", + "\t\texpectVal = [7, 10, 25, 30, 38, 40, 50, 60, 70, 80]\n", + "\t\tassert_equal(myTree.printInOrder(), expectVal)\n", + "\t\texpectVal = [1, 11, 21, 31, 41, 51, 61, 71, 81, 91]\n", + "\t\tassert_equal(myTree2.printInOrder(), expectVal)\n", + "\n", "\t\tprint(\"Test: insert checking with post order traversal\")\n", - "\t\tassert_equal(myTree.printPostOrder(), [7, 25, 10, 38, 40, 30, 60, 80, 70, 50])\n", - "\t\tassert_equal(myTree2.printPostOrder(), [91, 81, 71, 61, 51, 41, 31, 21, 11, 1])\n", + "\t\texpectVal = [7, 25, 10, 38, 40, 30, 60, 80, 70, 50]\n", + "\t\tassert_equal(myTree.printPostOrder(), expectVal)\n", + "\t\texpectVal = [91, 81, 71, 61, 51, 41, 31, 21, 11, 1]\n", + "\t\tassert_equal(myTree2.printPostOrder(), expectVal)\n", "\n", "\n", "\t\tprint(\"Test: insert checking with pre order traversal\")\n", - "\t\tassert_equal(myTree.printPreOrder(), [50, 30, 10, 7, 25, 40, 38, 70, 60, 80])\n", - "\t\tassert_equal(myTree2.printPreOrder(), [1, 11, 21, 31, 41, 51, 61, 71, 81, 91])\n", + "\t\texpectVal = [50, 30, 10, 7, 25, 40, 38, 70, 60, 80]\n", + "\t\tassert_equal(myTree.printPreOrder(), expectVal)\n", + "\t\texpectVal = [1, 11, 21, 31, 41, 51, 61, 71, 81, 91]\n", + "\t\tassert_equal(myTree2.printPreOrder(), expectVal)\n", "\n", "\n", "\t\tprint(\"Success: test_insert_traversals\")\n", @@ -427,6 +434,7 @@ "\t\t[myTree.insert(x) for x in range(1, 5)]\n", "\t\tmyTree.delete(2)\n", "\t\tassert_equal(myTree.root.rightChild.data, 3)\n", + " \n", "\t\tprint(\"Test: delete invalid value\")\n", "\t\tassert_equal(myTree.delete(100), False)\n", "\n", @@ -445,7 +453,7 @@ }, { "cell_type": "code", - "execution_count": 37, + "execution_count": 10, "metadata": { "collapsed": false }, @@ -472,15 +480,6 @@ "source": [ "%run -i test_binary_search_tree.py" ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [] } ], "metadata": { diff --git a/graphs_trees/binary_tree/test_binary_search_tree.py b/graphs_trees/binary_tree/test_binary_search_tree.py index 0b72f8b..2204d5f 100644 --- a/graphs_trees/binary_tree/test_binary_search_tree.py +++ b/graphs_trees/binary_tree/test_binary_search_tree.py @@ -1,6 +1,6 @@ from nose.tools import assert_equal -class TestBinaryTree(BinaryTree): +class TestBinaryTree(object): def test_insert_traversals (self): myTree = BinaryTree() @@ -10,16 +10,23 @@ class TestBinaryTree(BinaryTree): [myTree2.insert(num) for num in range (1, 100, 10)] print("Test: insert checking with in order traversal") - assert_equal(myTree.printInOrder(), [7, 10, 25, 30, 38, 40, 50, 60, 70, 80]) - assert_equal(myTree2.printInOrder(), [1, 11, 21, 31, 41, 51, 61, 71, 81, 91]) + expectVal = [7, 10, 25, 30, 38, 40, 50, 60, 70, 80] + assert_equal(myTree.printInOrder(), expectVal) + expectVal = [1, 11, 21, 31, 41, 51, 61, 71, 81, 91] + assert_equal(myTree2.printInOrder(), expectVal) + print("Test: insert checking with post order traversal") - assert_equal(myTree.printPostOrder(), [7, 25, 10, 38, 40, 30, 60, 80, 70, 50]) - assert_equal(myTree2.printPostOrder(), [91, 81, 71, 61, 51, 41, 31, 21, 11, 1]) + expectVal = [7, 25, 10, 38, 40, 30, 60, 80, 70, 50] + assert_equal(myTree.printPostOrder(), expectVal) + expectVal = [91, 81, 71, 61, 51, 41, 31, 21, 11, 1] + assert_equal(myTree2.printPostOrder(), expectVal) print("Test: insert checking with pre order traversal") - assert_equal(myTree.printPreOrder(), [50, 30, 10, 7, 25, 40, 38, 70, 60, 80]) - assert_equal(myTree2.printPreOrder(), [1, 11, 21, 31, 41, 51, 61, 71, 81, 91]) + expectVal = [50, 30, 10, 7, 25, 40, 38, 70, 60, 80] + assert_equal(myTree.printPreOrder(), expectVal) + expectVal = [1, 11, 21, 31, 41, 51, 61, 71, 81, 91] + assert_equal(myTree2.printPreOrder(), expectVal) print("Success: test_insert_traversals")