{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# The BSTree data structure\n", "\n", "## Agenda\n", "\n", "- API\n", "- Implementation\n", " - Search\n", " - Addition\n", " - Removal\n", " - Iteration / Traversal" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## API" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "class BSTree:\n", " class Node:\n", " def __init__(self, val, left=None, right=None):\n", " self.val = val\n", " self.left = left\n", " self.right = right\n", " \n", " def __init__(self):\n", " self.size = 0\n", " self.root = None\n", " \n", " def add(self, val):\n", " \"\"\"Adds `val` to this tree while maintaining BSTree properties.\"\"\"\n", " assert(val not in self)\n", " pass\n", " \n", " def __contains__(self, val):\n", " \"\"\"Returns `True` if val is in this tree and `False` otherwise.\"\"\"\n", " pass\n", " \n", " def __delitem__(self, val):\n", " \"\"\"Removes `val` from this tree while maintaining BSTree properties.\"\"\"\n", " assert(val in self)\n", " pass\n", " \n", " def __iter__(self):\n", " \"\"\"Returns an iterator over all the values in the tree, in ascending order.\"\"\"\n", " pass\n", "\n", " def __len__(self):\n", " return self.size\n", "\n", " def pprint(self, width=64):\n", " \"\"\"Attempts to pretty-print this tree's contents.\"\"\"\n", " height = self.height()\n", " nodes = [(self.root, 0)]\n", " prev_level = 0\n", " repr_str = ''\n", " while nodes:\n", " n,level = nodes.pop(0)\n", " if prev_level != level:\n", " prev_level = level\n", " repr_str += '\\n'\n", " if not n:\n", " if level < height-1:\n", " nodes.extend([(None, level+1), (None, level+1)])\n", " repr_str += '{val:^{width}}'.format(val='-', width=width//2**level)\n", " elif n:\n", " if n.left or level < height-1:\n", " nodes.append((n.left, level+1))\n", " if n.right or level < height-1:\n", " nodes.append((n.right, level+1))\n", " repr_str += '{val:^{width}}'.format(val=n.val, width=width//2**level)\n", " print(repr_str)\n", " \n", " def height(self):\n", " \"\"\"Returns the height of the longest branch of the tree.\"\"\"\n", " def height_rec(t):\n", " if not t:\n", " return 0\n", " else:\n", " return max(1+height_rec(t.left), 1+height_rec(t.right))\n", " return height_rec(self.root)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "t = BSTree()\n", "t.root = BSTree.Node(5,\n", " left=BSTree.Node(2),\n", " right=BSTree.Node(10))\n", "t.size = 3" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "t.pprint()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "t.height()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Implementation" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Search" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "class BSTree(BSTree):\n", " def __contains__(self, val):\n", " pass" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "t = BSTree()\n", "t.root = BSTree.Node(5,\n", " left=BSTree.Node(2),\n", " right=BSTree.Node(10))\n", "t.size = 3" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "5 in t" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Addition" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "class BSTree(BSTree):\n", " def add(self, val):\n", " assert(val not in self)\n", " pass" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import random\n", "t = BSTree()\n", "vals = list(range(5))\n", "random.shuffle(vals)\n", "for x in vals:\n", " t.add(x)\n", "t.pprint()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import random\n", "t = BSTree()\n", "vals = list(range(1, 10, 2))\n", "random.shuffle(vals)\n", "for x in vals:\n", " t.add(x)\n", "\n", "assert(all(x in t for x in range(1, 10, 2)))\n", "assert(all(x not in t for x in range(0, 12, 2)))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Removal" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "class BSTree(BSTree):\n", " def __delitem__(self, val):\n", " assert(val in self)\n", " # deal with relatively simple cases first!\n", " pass" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "t = BSTree()\n", "for x in [10, 5, 15, 2, 17]:\n", " t.add(x)\n", "t.pprint()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "del t[2]\n", "t.pprint()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "t = BSTree()\n", "for x in [10, 5, 15, 2, 17]:\n", " t.add(x)\n", "del t[5]\n", "t.pprint()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "t = BSTree()\n", "for x in [10, 5, 15, 2, 17]:\n", " t.add(x)\n", "del t[15]\n", "t.pprint()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "class BSTree(BSTree):\n", " def __delitem__(self, val):\n", " # fully working delete\n", " assert(val in self)\n", " pass" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "t = BSTree()\n", "for x in [10, 5, 2, 7, 9, 8, 1, 15, 12, 18]:\n", " t.add(x)\n", "t.pprint()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "del t[15]\n", "t.pprint()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "t = BSTree()\n", "for x in [10, 5, 2, 7, 9, 8, 1, 15, 12, 18]:\n", " t.add(x)\n", "del t[5]\n", "t.pprint()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "t = BSTree()\n", "for x in [10, 5, 2, 7, 9, 8, 1, 15, 12, 18]:\n", " t.add(x)\n", "del t[10]\n", "t.pprint()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Iteration / Traversal" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "class BSTree(BSTree):\n", " def __iter__(self):\n", " pass" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import random\n", "t = BSTree()\n", "vals = list(range(20))\n", "random.shuffle(vals)\n", "for x in vals:\n", " t.add(x)\n", "for x in t:\n", " print(x)" ] } ], "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.6.1" } }, "nbformat": 4, "nbformat_minor": 1 }