diff --git a/graphs_trees/.DS_Store b/graphs_trees/.DS_Store new file mode 100644 index 0000000..1a99e14 Binary files /dev/null and b/graphs_trees/.DS_Store differ 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 0000000..6abb336 Binary files /dev/null and b/graphs_trees/binary_tree/.DS_Store differ 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