{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Linked Structures\n", "\n", "## Agenda\n", "\n", "1. Motives\n", "2. Objectives\n", "3. Mechanisms" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 1. Motives" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "%matplotlib inline\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", "from timeit import timeit\n", "\n", "def time_array_front_insert_delete(n):\n", " return timeit('lst.insert(0, None) ; del lst[0]',\n", " 'lst = list(range({}))'.format(n),\n", " number=1000)\n", "\n", "ns = np.linspace(100, 10000, 50)\n", "plt.plot(ns, [time_array_front_insert_delete(int(n)) for n in ns], 'ro')\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# consider:\n", "\n", "def concatenate(arr1, arr2):\n", " \"\"\"Concatenates the contents of arr1 and arr2 as efficiently (time-wise)\n", " as possible, so that the resulting structure can be used to index all\n", " combined elements (arr1's followed by arr2's).\"\"\"\n", "\n", " # option 1:\n", " for x in arr2:\n", " arr1.append(x)\n", " return arr1\n", "\n", " # option 2:\n", " arr1.extend(arr2)\n", " return arr1\n", "\n", " # option 3:\n", " return arr1 + arr2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 2. Objectives\n", "\n", "We need a new data storage mechanism for constructing data structures that:\n", "\n", "- does not require monolithic, contiguous memory allocation,\n", "- allows individual elements to be flexibly and efficiently reorganized,\n", "- and preserves the ability to locate (e.g., via position) and iterate over elements" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 3. Mechanisms" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 3.1. Two-Element Lists" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# data items\n", "i1 = 'lions'\n", "i2 = 'tigers'\n", "i3 = 'bears'\n", "i4 = 'oh, my'" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# creating individual \"links\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# link-ing them together" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# iteration" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# prepending" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# insertion" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 3.2. \"Link\" objects" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "class Link:\n", " def __init__(self, val, next=None):\n", " self.val = val\n", " self.next = next" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# manually constructing a list" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# iteration" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# iteration based on a recursive pattern" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "class LinkedList:\n", " def __init__(self):\n", " self.head = None\n", " \n", " def prepend(self, val):\n", " self.head = Link(val, self.head)\n", " \n", " def __iter__(self):\n", " cursor = self.head\n", " while cursor:\n", " yield cursor.val\n", " cursor = cursor.next\n", " \n", " def __repr__(self):\n", " return '[' + ', '.join(str(x) for x in self) + ']'" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "class BinaryLink:\n", " def __init__(self, val, left=None, right=None):\n", " self.val = val\n", " self.left = left\n", " self.right = right" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# manual construction of a \"tree\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def tree_iter(root):\n", " if root:\n", " yield root.val\n", " yield from tree_iter(root.left)\n", " yield from tree_iter(root.right)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "class NaryLink:\n", " def __init__(self, val, n=2):\n", " self.val = val\n", " self.children = [None] * n\n", " \n", " def __getitem__(self, idx):\n", " return self.children[idx]\n", " \n", " def __setitem__(self, idx, val):\n", " self.children[idx] = val\n", " \n", " def __iter__(self):\n", " for c in self.children:\n", " yield c" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "root = NaryLink('Kingdoms', n=5)\n", "\n", "root[0] = NaryLink('Animalia', n=35)\n", "root[1] = NaryLink('Plantae', n=12)\n", "root[2] = NaryLink('Fungi', n=7)\n", "root[3] = NaryLink('Protista', n=5)\n", "root[4] = NaryLink('Monera', n=5)\n", "\n", "root[2][0] = NaryLink('Chytridiomycota')\n", "root[2][1] = NaryLink('Blastocladiomycota')\n", "root[2][2] = NaryLink('Glomeromycota')\n", "root[2][3] = NaryLink('Ascomycota')\n", "root[2][4] = NaryLink('Basidiomycota')\n", "root[2][5] = NaryLink('Microsporidia')\n", "root[2][6] = NaryLink('Neocallimastigomycota')\n", "\n", "def tree_iter(root):\n", " if root:\n", " yield root.val\n", " for c in root:\n", " yield from tree_iter(c)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false, "scrolled": true }, "outputs": [], "source": [ "for x in tree_iter(root):\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.4.3" } }, "nbformat": 4, "nbformat_minor": 0 }