{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Linked List" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": true }, "outputs": [], "source": [ "from enum import Enum" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": true }, "outputs": [], "source": [ "class Position(Enum):\n", " START = 0\n", " END = 2" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": true }, "outputs": [], "source": [ "class Node:\n", " def __init__(self, data):\n", " self.data = data\n", " self.next = None\n", " \n", " def __repr__(self):\n", " return f'{self.__class__.__name__}({self.data})'" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Insertions\n", "1. Start: **O(1)**\n", "1. Insert After: **O(n)**\n", "1. End: **O(1)**" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": true }, "outputs": [], "source": [ "class LinkedList:\n", " def __init__(self, ls = []):\n", " self.head = None\n", " self.tail = None\n", " self.count = len(ls)\n", " \n", " if self.count > 0:\n", " for item in ls:\n", " self._insertEnd(item)\n", " \n", " def _insertStart(self, data):\n", " self.count += 1\n", " \n", " tmp = Node(data)\n", " tmp.next = self.head\n", " self.head = tmp\n", " \n", " if self.tail is None:\n", " self.tail = self.head\n", " \n", " return tmp\n", " \n", " def _insertAfter(self, data, after):\n", " self.count += 1\n", "\n", " q = self.head\n", "\n", " while q is not None:\n", " if q.data == after:\n", " tmp = Node(data)\n", " tmp.next = q.next\n", " q.next = tmp\n", " \n", " if tmp.next is None:\n", " self.tail = tmp\n", " \n", " return tmp\n", " \n", " q = q.next\n", " \n", " def _insertEnd(self, data):\n", " self.count += 1\n", "\n", " if self.head is None:\n", " tmp = Node(data)\n", " self.head = self.tail = tmp\n", " return tmp\n", " \n", " tmp = Node(data)\n", " self.tail.next = tmp\n", " self.tail = self.tail.next\n", " \n", " return tmp" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Deletions\n", "1. Start: **O(1)**\n", "1. Delete Element: **O(n)**\n", "1. End: **O(n)**" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def _deleteStart(self):\n", " if self.count == 0:\n", " return\n", " \n", " self.count -= 1\n", " \n", " if self.head == self.tail:\n", " self.head = self.tail = None\n", " return\n", " \n", " tmp = self.head\n", " self.head = self.head.next\n", " \n", " return tmp\n", "\n", "def _deleteEle(self, ele):\n", " if self.count == 0 or (self.count == 1 and self.head.data != ele):\n", " return\n", " \n", " if self.head.data == ele:\n", " return self._deleteStart()\n", " \n", " q = self.head\n", " \n", " while q.next is not None:\n", " if q.next.data == ele:\n", " tmp = q.next\n", " q.next = tmp.next\n", " \n", " if q.next is None:\n", " self.tail = q\n", " \n", " self.count -= 1\n", " \n", " return tmp\n", " \n", " q = q.next\n", " \n", "\n", "def _deleteEnd(self):\n", " if self.count == 0:\n", " return\n", " \n", " self.count -= 1\n", "\n", " if self.head is self.tail:\n", " self.head = self.tail = None\n", " return\n", " \n", " q = self.head\n", "\n", " while q.next is not self.tail:\n", " q = q.next\n", "\n", " tmp = self.tail\n", " self.tail = q\n", " self.tail.next = None\n", "\n", " return tmp\n", "\n", "LinkedList._deleteEle = _deleteEle\n", "LinkedList._deleteStart = _deleteStart\n", "LinkedList._deleteEnd = _deleteEnd" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Public Interface" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def push(self, data, ele = Position.END):\n", " method = {\n", " Position.START: self._insertStart,\n", " Position.END: self._insertEnd\n", " }.get(ele, self._insertAfter)\n", "\n", " if method == self._insertAfter:\n", " return self._insertAfter(data, ele)\n", "\n", " return method(data)\n", "\n", "def pop(self, ele = Position.END):\n", " method = {\n", " Position.START: self._deleteStart,\n", " Position.END: self._deleteEnd\n", " }.get(ele, self._deleteEle)\n", "\n", " if method == self._deleteEle:\n", " return method(ele)\n", "\n", " return method()\n", "\n", "LinkedList.push = push\n", "LinkedList.pop = pop" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Dunders\n", "To make life easier" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "def __repr__(self): # For Debug purpose: it returns the string which upon executing, results in exact same object\n", " ls = []\n", " q = self.head\n", "\n", " while q is not None:\n", " ls.append(q.data)\n", " q = q.next\n", "\n", " return f'{self.__class__.__name__}({ls})'\n", "\n", "def __str__(self): # For User, pretty print of object\n", " q = self.head\n", "\n", " s = ''\n", "\n", " while q and q.next is not None:\n", " s += f'{q.data} -> '\n", " q = q.next\n", "\n", " s += f'{str(q.data)}' if q is not None else None\n", "\n", " return f'[{s}]'\n", "\n", "def __len__(self):\n", " return self.count\n", "\n", "LinkedList.__repr__ = __repr__\n", "LinkedList.__str__ = __str__\n", "LinkedList.__len__ = __len__" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Tests" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Linked List (7) : [0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6]\n" ] } ], "source": [ "ls = LinkedList()\n", "\n", "ls.push(3, Position.END)\n", "ls.push(1, Position.START)\n", "\n", "ls.push(4, ele = 3)\n", "ls.push(2, ele = 1)\n", "\n", "ls.push(0, Position.START)\n", "ls.push(5, Position.END)\n", "\n", "ls.push(6)\n", "\n", "print(f\"Linked List ({len(ls)}) : {ls}\")" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "LinkedList([0, 1, 2, 3, 4, 5, 6])" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ls" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6]\n" ] } ], "source": [ "print(LinkedList([0, 1, 2, 3, 4, 5, 6])) # Yield same result as all the above statements" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Linked List (4) : [1 -> 2 -> 4 -> 5]\n" ] } ], "source": [ "ls.pop(Position.START)\n", "ls.pop(3)\n", "ls.pop(Position.END)\n", "print(f\"Linked List ({len(ls)}) : {ls}\")" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "LinkedList([1, 2, 4, 5])" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ls" ] } ], "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.2" } }, "nbformat": 4, "nbformat_minor": 2 }