{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Sebastian Raschka \n", "last updated: 2017-07-24 \n", "\n", "CPython 3.6.1\n", "IPython 6.0.0\n" ] } ], "source": [ "%load_ext watermark\n", "%watermark -a 'Sebastian Raschka' -u -d -v" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Bubble Sort" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Quick note about Bubble sort" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "I don't want to get into the details about sorting algorithms here, but there is a great report \n", "[\"Sorting in the Presence of Branch Prediction and Caches - Fast Sorting on Modern Computers\"](https://www.cs.tcd.ie/publications/tech-reports/reports.05/TCD-CS-2005-57.pdf) written by Paul Biggar and David Gregg, where they describe and analyze elementary sorting algorithms in very nice detail (see chapter 4). \n", "\n", "And for a quick reference, [this website](http://www.sorting-algorithms.com/bubble-sort) has a nice animation of this algorithm." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A long story short: The \"worst-case\" complexity of the Bubble sort algorithm (i.e., \"Big-O\") \n", " $\\Rightarrow \\pmb O(n^2)$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Bubble sort implemented in (C)Python" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "def python_bubblesort(a_list):\n", " \"\"\" Bubblesort in Python for list objects (sorts in place).\"\"\"\n", " length = len(a_list)\n", " for i in range(length):\n", " for j in range(1, length):\n", " if a_list[j] < a_list[j-1]:\n", " a_list[j-1], a_list[j] = a_list[j], a_list[j-1]\n", " return a_list" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "Below is a improved version that quits early if no further swap is needed." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "def python_bubblesort_improved(a_list):\n", " \"\"\" Bubblesort in Python for list objects (sorts in place).\"\"\"\n", " length = len(a_list)\n", " swapped = 1\n", " for i in range(length):\n", " if swapped: \n", " swapped = 0\n", " for ele in range(length-i-1):\n", " if a_list[ele] > a_list[ele + 1]:\n", " temp = a_list[ele + 1]\n", " a_list[ele + 1] = a_list[ele]\n", " a_list[ele] = temp\n", " swapped = 1\n", " return a_list" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Verifying that all implementations work correctly" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Bubblesort works correctly\n" ] } ], "source": [ "import random\n", "import copy\n", "random.seed(4354353)\n", "\n", "l = [random.randint(1,1000) for num in range(1, 1000)]\n", "l_sorted = sorted(l)\n", "for f in [python_bubblesort, python_bubblesort_improved]:\n", " assert(l_sorted == f(copy.copy(l)))\n", "print('Bubblesort works correctly')\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Performance comparison" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "100 loops, best of 3: 1.42 ms per loop\n", "The slowest run took 95.97 times longer than the fastest. This could mean that an intermediate result is being cached.\n", "10000 loops, best of 3: 24.8 µs per loop\n" ] } ], "source": [ "# small list\n", "\n", "l_small = [random.randint(1,100) for num in range(1, 100)]\n", "l_small_cp = copy.copy(l_small)\n", "\n", "%timeit python_bubblesort(l_small)\n", "%timeit python_bubblesort_improved(l_small_cp)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 loop, best of 3: 19.5 s per loop\n", "The slowest run took 7804.31 times longer than the fastest. This could mean that an intermediate result is being cached.\n", "1 loop, best of 3: 2.45 ms per loop\n" ] } ], "source": [ "# larger list\n", "\n", "l_small = [random.randint(1,10000) for num in range(1, 10000)]\n", "l_small_cp = copy.copy(l_small)\n", "\n", "%timeit python_bubblesort(l_small)\n", "%timeit python_bubblesort_improved(l_small_cp)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "
" ] } ], "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 }