{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import numpy as np\n", "from bokeh.plotting import figure, show, output_notebook\n", "from bokeh.io import push_notebook\n", "from time import sleep" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## algorithm" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": true }, "outputs": [], "source": [ "class Node:\n", " def __init__(self, value, left=None, right=None, red=False):\n", " self.value = value\n", " self.left = left\n", " self.right = right\n", " self.red = red\n", "\n", " @staticmethod\n", " def red(node):\n", " return node and node.red\n", "\n", " def rotate_left(self):\n", " if not Node.red(self.left) and Node.red(self.right):\n", " child = self.right\n", " self.right, child.left = child.left, self\n", " self.red, child.red = True, self.red\n", " return child\n", " else:\n", " return self\n", "\n", " def rotate_right(self):\n", " if Node.red(self.left) and Node.red(self.left.left):\n", " child = self.left\n", " self.left, child.right = child.right, self\n", " self.red, child.red = True, self.red\n", " return child\n", " else:\n", " return self\n", " \n", " def flip_colors(self):\n", " if Node.red(self.left) and Node.red(self.right):\n", " self.red, self.left.red, self.right.red = True, False, False" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [], "source": [ "def insert(node, value, root=True):\n", " if not node:\n", " return Node(value, red=not root)\n", " \n", " # insert value\n", " if value == node.value:\n", " pass\n", " elif value < node.value:\n", " node.left = insert(node.left, value, root=False)\n", " else:\n", " node.right = insert(node.right, value, root=False)\n", " \n", " # update tree w.r.t invariants\n", " node = node.rotate_left()\n", " node = node.rotate_right()\n", " node.flip_colors()\n", "\n", " # keep root black\n", " if root:\n", " node.red = False\n", "\n", " return node" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def draw(node, red, black, xlo=0, xhi=1, x=.5, y=0):\n", " if node:\n", " x_, y_ = (xlo + xhi) / 2, y - 1\n", " (red if node.red else black).append([x, y, x_, y_])\n", " draw(node.left, red, black, xlo, x_, x_, y_)\n", " draw(node.right, red, black, x_, xhi, x_, y_)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## run" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# insert few values\n", "root = None\n", "for i in range(5):\n", " root = insert(root, i)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "\n", "
" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": [ "\n", "(function(global) {\n", " function now() {\n", " return new Date();\n", " }\n", "\n", " var force = true;\n", "\n", " if (typeof (window._bokeh_onload_callbacks) === \"undefined\" || force === true) {\n", " window._bokeh_onload_callbacks = [];\n", " window._bokeh_is_loading = undefined;\n", " }\n", "\n", "\n", " \n", " if (typeof (window._bokeh_timeout) === \"undefined\" || force === true) {\n", " window._bokeh_timeout = Date.now() + 5000;\n", " window._bokeh_failed_load = false;\n", " }\n", "\n", " var NB_LOAD_WARNING = {'data': {'text/html':\n", " \"\\n\"+\n", " \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n", " \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n", " \"
\\n\"+\n", " \"\\n\"+\n",
" \"from bokeh.resources import INLINE\\n\"+\n",
" \"output_notebook(resources=INLINE)\\n\"+\n",
" \"\\n\"+\n",
" \"