├── .gitignore ├── .ipynb_checkpoints ├── Graphs-1-checkpoint.ipynb ├── Misc Data Structures-checkpoint.ipynb └── Vaccum_cleaner-checkpoint.ipynb ├── Algorithms ├── Bubble_sort.py ├── Count_inversion.py ├── Dselect.py ├── Insertion_sort.py ├── MergeSort.py ├── QuickSelect-1.py ├── Quicksort-1.py ├── Quicksort-2.py ├── Quicksort_InPlac2.py ├── Quicksort_InPlace.py ├── Random_Select_InPlace.py └── Selection_sort.py ├── Data Structures ├── Common_data_structures_class.py ├── Common_data_structures_test.py ├── Graph-1.py ├── Graph1.py ├── Graphs-1.ipynb ├── LinkedList-test.py ├── LinkedList.ipynb ├── LinkedList.py ├── Misc Data Structures.ipynb ├── Stack-Queue-using-List.py ├── Stack-using-LinkedList.ipynb └── Trees_class.py ├── LICENSE ├── README.md └── __pycache__ └── Common_data_structures_class.cpython-36.pyc /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *.cover 47 | .hypothesis/ 48 | 49 | # Translations 50 | *.mo 51 | *.pot 52 | 53 | # Django stuff: 54 | *.log 55 | local_settings.py 56 | 57 | # Flask stuff: 58 | instance/ 59 | .webassets-cache 60 | 61 | # Scrapy stuff: 62 | .scrapy 63 | 64 | # Sphinx documentation 65 | docs/_build/ 66 | 67 | # PyBuilder 68 | target/ 69 | 70 | # Jupyter Notebook 71 | .ipynb_checkpoints 72 | 73 | # pyenv 74 | .python-version 75 | 76 | # celery beat schedule file 77 | celerybeat-schedule 78 | 79 | # SageMath parsed files 80 | *.sage.py 81 | 82 | # dotenv 83 | .env 84 | 85 | # virtualenv 86 | .venv 87 | venv/ 88 | ENV/ 89 | 90 | # Spyder project settings 91 | .spyderproject 92 | .spyproject 93 | 94 | # Rope project settings 95 | .ropeproject 96 | 97 | # mkdocs documentation 98 | /site 99 | 100 | # mypy 101 | .mypy_cache/ 102 | -------------------------------------------------------------------------------- /.ipynb_checkpoints/Graphs-1-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "### Class Node" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": {}, 14 | "outputs": [], 15 | "source": [ 16 | "class Node (object):\n", 17 | " def __init__(self,name):\n", 18 | " self.name=name\n", 19 | " \n", 20 | " def getName(self):\n", 21 | " return (self.name)\n", 22 | " \n", 23 | " def __str__(self):\n", 24 | " return (self.name)" 25 | ] 26 | }, 27 | { 28 | "cell_type": "markdown", 29 | "metadata": {}, 30 | "source": [ 31 | "### Class Edge" 32 | ] 33 | }, 34 | { 35 | "cell_type": "code", 36 | "execution_count": 2, 37 | "metadata": {}, 38 | "outputs": [], 39 | "source": [ 40 | "class Edge (object):\n", 41 | " def __init__(self,src,dest):\n", 42 | " self.src=src\n", 43 | " self.dest=dest\n", 44 | " \n", 45 | " def getSource(self):\n", 46 | " return (self.src)\n", 47 | " \n", 48 | " def getDest(self):\n", 49 | " return (self.dest)\n", 50 | " \n", 51 | " def __str__(self):\n", 52 | " return (self.src.getName()+\"->\"+self.dest.getName())" 53 | ] 54 | }, 55 | { 56 | "cell_type": "markdown", 57 | "metadata": {}, 58 | "source": [ 59 | "### Class Digraph" 60 | ] 61 | }, 62 | { 63 | "cell_type": "code", 64 | "execution_count": 3, 65 | "metadata": {}, 66 | "outputs": [], 67 | "source": [ 68 | "class Digraph(object):\n", 69 | " def __init__(self):\n", 70 | " self.edges={}\n", 71 | " \n", 72 | " def addNode(self,node):\n", 73 | " if node in self.edges:\n", 74 | " raise ValueError(\"Duplicate node\")\n", 75 | " else:\n", 76 | " self.edges[node]=[]\n", 77 | " print(f\"{node.getName()} added to the graph\")\n", 78 | " \n", 79 | " def addEdge(self,edge):\n", 80 | " src=edge.getSource()\n", 81 | " print(src)\n", 82 | " dest=edge.getDest()\n", 83 | " print(dest)\n", 84 | " if not (src in self.edges and dest in self.edges):\n", 85 | " raise ValueError(\"Node not in graph\")\n", 86 | " else:\n", 87 | " self.edges[src].append(dest) # Builds adjacency list\n", 88 | " \n", 89 | " def childrenOf(self,node):\n", 90 | " return self.edges[node]\n", 91 | " \n", 92 | " def hasNode(self,node):\n", 93 | " return node in self.edges\n", 94 | " \n", 95 | " def getNode(self,name):\n", 96 | " for n in self.edges:\n", 97 | " if n.getName()==name:\n", 98 | " return n\n", 99 | " raise NameError(name)\n", 100 | " \n", 101 | " def __str__(self):\n", 102 | " toPrint=''\n", 103 | " for src in self.edges:\n", 104 | " for dest in self.edges[src]:\n", 105 | " toPrint=toPrint+src.getName()+\"->\"+dest.getName()+\"\\n\"\n", 106 | " \n", 107 | " if (toPrint==''):\n", 108 | " return (\"Empty graph! Nothing to print\")\n", 109 | " else:\n", 110 | " return toPrint[:-1]" 111 | ] 112 | }, 113 | { 114 | "cell_type": "code", 115 | "execution_count": 4, 116 | "metadata": {}, 117 | "outputs": [], 118 | "source": [ 119 | "cities=['Chicago','Boston','New York','Salt Lake City','SFO','Seattle']" 120 | ] 121 | }, 122 | { 123 | "cell_type": "code", 124 | "execution_count": 5, 125 | "metadata": {}, 126 | "outputs": [], 127 | "source": [ 128 | "g=Digraph()" 129 | ] 130 | }, 131 | { 132 | "cell_type": "code", 133 | "execution_count": 6, 134 | "metadata": {}, 135 | "outputs": [], 136 | "source": [ 137 | "nodes=[]\n", 138 | "for c in cities:\n", 139 | " nodes.append(Node(c))" 140 | ] 141 | }, 142 | { 143 | "cell_type": "code", 144 | "execution_count": 7, 145 | "metadata": {}, 146 | "outputs": [ 147 | { 148 | "data": { 149 | "text/plain": [ 150 | "{}" 151 | ] 152 | }, 153 | "execution_count": 7, 154 | "metadata": {}, 155 | "output_type": "execute_result" 156 | } 157 | ], 158 | "source": [ 159 | "g.edges" 160 | ] 161 | }, 162 | { 163 | "cell_type": "code", 164 | "execution_count": 8, 165 | "metadata": {}, 166 | "outputs": [ 167 | { 168 | "name": "stdout", 169 | "output_type": "stream", 170 | "text": [ 171 | "Chicago added to the graph\n", 172 | "Boston added to the graph\n", 173 | "New York added to the graph\n", 174 | "Salt Lake City added to the graph\n", 175 | "SFO added to the graph\n", 176 | "Seattle added to the graph\n" 177 | ] 178 | } 179 | ], 180 | "source": [ 181 | "for n in nodes:\n", 182 | " g.addNode(n)" 183 | ] 184 | }, 185 | { 186 | "cell_type": "code", 187 | "execution_count": 9, 188 | "metadata": {}, 189 | "outputs": [ 190 | { 191 | "data": { 192 | "text/plain": [ 193 | "{<__main__.Node at 0x1f5464b3cf8>: [],\n", 194 | " <__main__.Node at 0x1f5464b3a58>: [],\n", 195 | " <__main__.Node at 0x1f5464b3a90>: [],\n", 196 | " <__main__.Node at 0x1f5464b3c88>: [],\n", 197 | " <__main__.Node at 0x1f5464b3c50>: [],\n", 198 | " <__main__.Node at 0x1f5464b3cc0>: []}" 199 | ] 200 | }, 201 | "execution_count": 9, 202 | "metadata": {}, 203 | "output_type": "execute_result" 204 | } 205 | ], 206 | "source": [ 207 | "g.edges" 208 | ] 209 | }, 210 | { 211 | "cell_type": "code", 212 | "execution_count": 10, 213 | "metadata": {}, 214 | "outputs": [ 215 | { 216 | "name": "stdout", 217 | "output_type": "stream", 218 | "text": [ 219 | "Chicago\n", 220 | "Boston\n", 221 | "New York\n", 222 | "Salt Lake City\n", 223 | "SFO\n", 224 | "Seattle\n" 225 | ] 226 | } 227 | ], 228 | "source": [ 229 | "for k in g.edges:\n", 230 | " print(k)" 231 | ] 232 | }, 233 | { 234 | "cell_type": "code", 235 | "execution_count": 11, 236 | "metadata": {}, 237 | "outputs": [ 238 | { 239 | "data": { 240 | "text/plain": [ 241 | "<__main__.Node at 0x1f5464b3cf8>" 242 | ] 243 | }, 244 | "execution_count": 11, 245 | "metadata": {}, 246 | "output_type": "execute_result" 247 | } 248 | ], 249 | "source": [ 250 | "nodes[1]" 251 | ] 252 | }, 253 | { 254 | "cell_type": "code", 255 | "execution_count": 12, 256 | "metadata": {}, 257 | "outputs": [], 258 | "source": [ 259 | "edge_chicago_boston=Edge(nodes[0],nodes[1])" 260 | ] 261 | }, 262 | { 263 | "cell_type": "code", 264 | "execution_count": 13, 265 | "metadata": {}, 266 | "outputs": [ 267 | { 268 | "data": { 269 | "text/plain": [ 270 | "<__main__.Node at 0x1f5464b3a58>" 271 | ] 272 | }, 273 | "execution_count": 13, 274 | "metadata": {}, 275 | "output_type": "execute_result" 276 | } 277 | ], 278 | "source": [ 279 | "edge_chicago_boston.getSource()" 280 | ] 281 | }, 282 | { 283 | "cell_type": "code", 284 | "execution_count": 14, 285 | "metadata": {}, 286 | "outputs": [ 287 | { 288 | "data": { 289 | "text/plain": [ 290 | "True" 291 | ] 292 | }, 293 | "execution_count": 14, 294 | "metadata": {}, 295 | "output_type": "execute_result" 296 | } 297 | ], 298 | "source": [ 299 | "g.hasNode(nodes[2])" 300 | ] 301 | }, 302 | { 303 | "cell_type": "code", 304 | "execution_count": 15, 305 | "metadata": {}, 306 | "outputs": [ 307 | { 308 | "data": { 309 | "text/plain": [ 310 | "<__main__.Node at 0x1f5464b3c88>" 311 | ] 312 | }, 313 | "execution_count": 15, 314 | "metadata": {}, 315 | "output_type": "execute_result" 316 | } 317 | ], 318 | "source": [ 319 | "g.getNode('SFO')" 320 | ] 321 | }, 322 | { 323 | "cell_type": "code", 324 | "execution_count": 16, 325 | "metadata": {}, 326 | "outputs": [], 327 | "source": [ 328 | "from graphviz import Graph\n", 329 | "dot=Graph(\"Roundtable\")" 330 | ] 331 | }, 332 | { 333 | "cell_type": "code", 334 | "execution_count": 17, 335 | "metadata": {}, 336 | "outputs": [], 337 | "source": [ 338 | "dot.node('A', 'King Arthur')\n", 339 | "dot.node('B', 'Sir Bedevere the Wise')\n", 340 | "dot.node('L', 'Sir Lancelot the Brave')" 341 | ] 342 | }, 343 | { 344 | "cell_type": "code", 345 | "execution_count": 18, 346 | "metadata": {}, 347 | "outputs": [], 348 | "source": [ 349 | "dot.edges(['AB', 'AL'])" 350 | ] 351 | }, 352 | { 353 | "cell_type": "code", 354 | "execution_count": 19, 355 | "metadata": {}, 356 | "outputs": [ 357 | { 358 | "name": "stdout", 359 | "output_type": "stream", 360 | "text": [ 361 | "graph Roundtable {\n", 362 | "\tA [label=\"King Arthur\"]\n", 363 | "\tB [label=\"Sir Bedevere the Wise\"]\n", 364 | "\tL [label=\"Sir Lancelot the Brave\"]\n", 365 | "\tA -- B\n", 366 | "\tA -- L\n", 367 | "}\n" 368 | ] 369 | } 370 | ], 371 | "source": [ 372 | " print(dot.source)" 373 | ] 374 | }, 375 | { 376 | "cell_type": "code", 377 | "execution_count": 26, 378 | "metadata": {}, 379 | "outputs": [], 380 | "source": [ 381 | "import os\n", 382 | "os.environ[\"PATH\"] += os.pathsep + \"C:\\\\Program Files (x86)\\\\Graphviz2.38\\\\bin\\\\\"" 383 | ] 384 | }, 385 | { 386 | "cell_type": "code", 387 | "execution_count": 29, 388 | "metadata": {}, 389 | "outputs": [ 390 | { 391 | "data": { 392 | "text/plain": [ 393 | "'test-output/round-table.gv.pdf'" 394 | ] 395 | }, 396 | "execution_count": 29, 397 | "metadata": {}, 398 | "output_type": "execute_result" 399 | } 400 | ], 401 | "source": [ 402 | "dot.render(view=True,cleanup=True)" 403 | ] 404 | }, 405 | { 406 | "cell_type": "code", 407 | "execution_count": 30, 408 | "metadata": {}, 409 | "outputs": [ 410 | { 411 | "data": { 412 | "text/plain": [ 413 | "'test-output/round-table.gv.pdf'" 414 | ] 415 | }, 416 | "execution_count": 30, 417 | "metadata": {}, 418 | "output_type": "execute_result" 419 | } 420 | ], 421 | "source": [ 422 | "dot.view()" 423 | ] 424 | }, 425 | { 426 | "cell_type": "code", 427 | "execution_count": 31, 428 | "metadata": {}, 429 | "outputs": [ 430 | { 431 | "data": { 432 | "image/svg+xml": [ 433 | "\r\n", 434 | "\r\n", 436 | "\r\n", 438 | "\r\n", 439 | "\r\n", 441 | "\r\n", 442 | "Roundtable\r\n", 443 | "\r\n", 444 | "\r\n", 445 | "A\r\n", 446 | "\r\n", 447 | "King Arthur\r\n", 448 | "\r\n", 449 | "\r\n", 450 | "B\r\n", 451 | "\r\n", 452 | "Sir Bedevere the Wise\r\n", 453 | "\r\n", 454 | "\r\n", 455 | "A--B\r\n", 456 | "\r\n", 457 | "\r\n", 458 | "\r\n", 459 | "L\r\n", 460 | "\r\n", 461 | "Sir Lancelot the Brave\r\n", 462 | "\r\n", 463 | "\r\n", 464 | "A--L\r\n", 465 | "\r\n", 466 | "\r\n", 467 | "\r\n", 468 | "\r\n" 469 | ], 470 | "text/plain": [ 471 | "" 472 | ] 473 | }, 474 | "execution_count": 31, 475 | "metadata": {}, 476 | "output_type": "execute_result" 477 | } 478 | ], 479 | "source": [ 480 | "dot" 481 | ] 482 | }, 483 | { 484 | "cell_type": "code", 485 | "execution_count": 33, 486 | "metadata": {}, 487 | "outputs": [ 488 | { 489 | "name": "stdout", 490 | "output_type": "stream", 491 | "text": [ 492 | "test-output/round-table.gv.pdf\n" 493 | ] 494 | } 495 | ], 496 | "source": [ 497 | "print(dot.view())" 498 | ] 499 | }, 500 | { 501 | "cell_type": "code", 502 | "execution_count": null, 503 | "metadata": {}, 504 | "outputs": [], 505 | "source": [] 506 | } 507 | ], 508 | "metadata": { 509 | "kernelspec": { 510 | "display_name": "Python 3", 511 | "language": "python", 512 | "name": "python3" 513 | }, 514 | "language_info": { 515 | "codemirror_mode": { 516 | "name": "ipython", 517 | "version": 3 518 | }, 519 | "file_extension": ".py", 520 | "mimetype": "text/x-python", 521 | "name": "python", 522 | "nbconvert_exporter": "python", 523 | "pygments_lexer": "ipython3", 524 | "version": "3.6.2" 525 | }, 526 | "latex_envs": { 527 | "LaTeX_envs_menu_present": true, 528 | "autoclose": false, 529 | "autocomplete": true, 530 | "bibliofile": "biblio.bib", 531 | "cite_by": "apalike", 532 | "current_citInitial": 1, 533 | "eqLabelWithNumbers": true, 534 | "eqNumInitial": 1, 535 | "hotkeys": { 536 | "equation": "Ctrl-E", 537 | "itemize": "Ctrl-I" 538 | }, 539 | "labels_anchors": false, 540 | "latex_user_defs": false, 541 | "report_style_numbering": false, 542 | "user_envs_cfg": false 543 | } 544 | }, 545 | "nbformat": 4, 546 | "nbformat_minor": 2 547 | } 548 | -------------------------------------------------------------------------------- /.ipynb_checkpoints/Misc Data Structures-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Stack" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": null, 13 | "metadata": {}, 14 | "outputs": [], 15 | "source": [ 16 | "class Stack:\n", 17 | " \"\"\"\n", 18 | " Stack data structure using list\n", 19 | " \"\"\"\n", 20 | " def __init__(self,value=None,name=None,verbose=False):\n", 21 | " \"\"\"\n", 22 | " Class initializer: Produces a stack with a single value or a list of values\n", 23 | " value: The initial value. Could be a list of a single item.\n", 24 | " name: Optional name for the stack.\n", 25 | " verbose: Boolean. Determines if each stack operation prints the item being pushed or popped.\n", 26 | " \"\"\"\n", 27 | " self._items = []\n", 28 | " self._height=0\n", 29 | " self._verbose=verbose\n", 30 | " \n", 31 | " if value!=None: \n", 32 | " if type(value)==list:\n", 33 | " for v in value:\n", 34 | " self._items.append(v)\n", 35 | " self._height = len(value)\n", 36 | " else:\n", 37 | " self._items.append(value)\n", 38 | " self._height = 1\n", 39 | " else:\n", 40 | " print(\"Empty stack created.\")\n", 41 | " \n", 42 | " if name!=None:\n", 43 | " self._name=str(name)\n", 44 | " else:\n", 45 | " self._name=''\n", 46 | " \n", 47 | " def pop(self):\n", 48 | " if self._height == 0:\n", 49 | " print (\"Stack is empty. Nothing to pop.\")\n", 50 | " return None\n", 51 | " else:\n", 52 | " self._height -=1\n", 53 | " item=self._items.pop()\n", 54 | " if self._verbose:\n", 55 | " print(\"{} popped\".format(item))\n", 56 | " return item\n", 57 | " \n", 58 | " def push(self,value=None):\n", 59 | " \"\"\"\n", 60 | " Pushes a a single value or a list of values onto the stack\n", 61 | " \"\"\"\n", 62 | " if value!=None: \n", 63 | " if type(value)==list:\n", 64 | " for v in value:\n", 65 | " self._items.append(v)\n", 66 | " if self._verbose:\n", 67 | " print(\"{} pushed\".format(v))\n", 68 | " self._height += len(value)\n", 69 | " else:\n", 70 | " self._height +=1\n", 71 | " self._items.append(value)\n", 72 | " if self._verbose:\n", 73 | " print(\"{} pushed\".format(value))\n", 74 | " else:\n", 75 | " if self._verbose:\n", 76 | " print(\"No value supplied, nothing was pushed.\")\n", 77 | " \n", 78 | " def isEmpty(self):\n", 79 | " \"\"\"\n", 80 | " Returns (Boolean) if the stack is empty\n", 81 | " \"\"\"\n", 82 | " return self._height==0\n", 83 | " \n", 84 | " def draw(self):\n", 85 | " \"\"\"\n", 86 | " Prints the stack structure as a vertical representation \n", 87 | " \"\"\"\n", 88 | " if self.isEmpty():\n", 89 | " pass\n", 90 | " return None\n", 91 | " else:\n", 92 | " print(\"=\"*15)\n", 93 | " n=self._height\n", 94 | " print('['+str(self._items[n-1])+']')\n", 95 | " for i in range(n-2,-1,-1):\n", 96 | " print(\" | \")\n", 97 | " print('['+str(self._items[i])+']')\n", 98 | " print(\"=\"*15)\n", 99 | " \n", 100 | " def height(self):\n", 101 | " \"\"\"\n", 102 | " Returns stack height\n", 103 | " \"\"\"\n", 104 | " return (self._height)\n", 105 | " \n", 106 | " def __str__(self):\n", 107 | " \"\"\"\n", 108 | " Returns stack name to print method\n", 109 | " \"\"\"\n", 110 | " return (self._name)\n", 111 | " \n", 112 | " def set_verbosity(self,boolean):\n", 113 | " \"\"\"\n", 114 | " Sets the verbosity of the stack operation\n", 115 | " \"\"\"\n", 116 | " self._verbose=boolean" 117 | ] 118 | }, 119 | { 120 | "cell_type": "code", 121 | "execution_count": null, 122 | "metadata": {}, 123 | "outputs": [], 124 | "source": [ 125 | "s=Stack('start',name='TestStack')\n", 126 | "for i in range(2,12,2):\n", 127 | " s.push(i)\n", 128 | "s.draw()" 129 | ] 130 | }, 131 | { 132 | "cell_type": "code", 133 | "execution_count": null, 134 | "metadata": {}, 135 | "outputs": [], 136 | "source": [ 137 | "s.pop()\n", 138 | "s.pop()\n", 139 | "s.draw()" 140 | ] 141 | }, 142 | { 143 | "cell_type": "code", 144 | "execution_count": null, 145 | "metadata": { 146 | "scrolled": false 147 | }, 148 | "outputs": [], 149 | "source": [ 150 | "s=Stack('start',name='TestStack')\n", 151 | "s.draw()\n", 152 | "for i in range(2,12,2):\n", 153 | " s.push(i)\n", 154 | " s.draw()\n", 155 | "for i in range(3):\n", 156 | " s.pop()\n", 157 | " s.draw()\n", 158 | "s.push(100)\n", 159 | "s.draw()\n", 160 | "s.pop()\n", 161 | "s.pop()\n", 162 | "s.draw()\n", 163 | "s.push([3,5,7])\n", 164 | "s.draw()\n", 165 | "s.draw()" 166 | ] 167 | }, 168 | { 169 | "cell_type": "markdown", 170 | "metadata": {}, 171 | "source": [ 172 | "## Queue" 173 | ] 174 | }, 175 | { 176 | "cell_type": "code", 177 | "execution_count": null, 178 | "metadata": {}, 179 | "outputs": [], 180 | "source": [ 181 | "class Queue:\n", 182 | " \"\"\"\n", 183 | " Queue data structure using list\n", 184 | " \"\"\"\n", 185 | " def __init__(self,value=None,name=None,verbose=False):\n", 186 | " \"\"\"\n", 187 | " Class initializer: Produces a queue with a single value or a list of values\n", 188 | " value: The initial value. Could be a list of a single item.\n", 189 | " name: Optional name for the queue.\n", 190 | " verbose: Boolean. Determines if each queue operation prints the item being pushed or popped.\n", 191 | " \"\"\"\n", 192 | " self._items = []\n", 193 | " self._length=0\n", 194 | " self._verbose=verbose\n", 195 | " \n", 196 | " if value!=None: \n", 197 | " if type(value)==list:\n", 198 | " for v in value:\n", 199 | " self._items.append(v)\n", 200 | " self._length = len(value)\n", 201 | " else:\n", 202 | " self._items.append(value)\n", 203 | " self._length = 1\n", 204 | " else:\n", 205 | " print(\"Empty queue created.\")\n", 206 | " \n", 207 | " if name!=None:\n", 208 | " self._name=str(name)\n", 209 | " else:\n", 210 | " self._name=''\n", 211 | " \n", 212 | " def dequeue(self):\n", 213 | " if self._length == 0:\n", 214 | " print (\"Queue is empty. Nothing to pop.\")\n", 215 | " return None\n", 216 | " else:\n", 217 | " self._length -=1\n", 218 | " item=self._items.pop(0)\n", 219 | " if self._verbose:\n", 220 | " print(\"{} dequeued\".format(item))\n", 221 | " return item\n", 222 | " \n", 223 | " def enqueue(self,value=None):\n", 224 | " \"\"\"\n", 225 | " Pushes a a single value or a list of values onto the queue\n", 226 | " \"\"\"\n", 227 | " if value!=None: \n", 228 | " if type(value)==list:\n", 229 | " for v in value:\n", 230 | " self._items.append(v)\n", 231 | " if self._verbose:\n", 232 | " print(\"{} enqueued\".format(v))\n", 233 | " self._length += len(value)\n", 234 | " else:\n", 235 | " self._length +=1\n", 236 | " self._items.append(value)\n", 237 | " if self._verbose:\n", 238 | " print(\"{} enqueued\".format(value))\n", 239 | " else:\n", 240 | " if self._verbose:\n", 241 | " print(\"No value supplied, nothing was enqueued.\")\n", 242 | " \n", 243 | " def isEmpty(self):\n", 244 | " \"\"\"\n", 245 | " Returns (Boolean) if the queue is empty\n", 246 | " \"\"\"\n", 247 | " return self._length==0\n", 248 | " \n", 249 | " def draw(self):\n", 250 | " if self.isEmpty():\n", 251 | " pass\n", 252 | " return None\n", 253 | " else:\n", 254 | " n=self._length\n", 255 | " for i in range(n-1):\n", 256 | " print('['+str(self._items[i])+']-',end='')\n", 257 | " print('['+str(self._items[n-1])+']')\n", 258 | " \n", 259 | " def length(self):\n", 260 | " \"\"\"\n", 261 | " Returns queue height\n", 262 | " \"\"\"\n", 263 | " return (self._length)\n", 264 | " \n", 265 | " def __str__(self):\n", 266 | " \"\"\"\n", 267 | " Returns queue name to print method\n", 268 | " \"\"\"\n", 269 | " return (self._name)\n", 270 | " \n", 271 | " def set_verbosity(self,boolean):\n", 272 | " \"\"\"\n", 273 | " Sets the verbosity of the queue operation\n", 274 | " \"\"\"\n", 275 | " self._verbose=boolean" 276 | ] 277 | }, 278 | { 279 | "cell_type": "code", 280 | "execution_count": null, 281 | "metadata": {}, 282 | "outputs": [], 283 | "source": [ 284 | "q=Queue([2,3,6],verbose=True)" 285 | ] 286 | }, 287 | { 288 | "cell_type": "code", 289 | "execution_count": null, 290 | "metadata": {}, 291 | "outputs": [], 292 | "source": [ 293 | "q" 294 | ] 295 | }, 296 | { 297 | "cell_type": "code", 298 | "execution_count": null, 299 | "metadata": {}, 300 | "outputs": [], 301 | "source": [ 302 | "q.draw()" 303 | ] 304 | }, 305 | { 306 | "cell_type": "code", 307 | "execution_count": null, 308 | "metadata": {}, 309 | "outputs": [], 310 | "source": [ 311 | "q.enqueue(10)" 312 | ] 313 | }, 314 | { 315 | "cell_type": "code", 316 | "execution_count": null, 317 | "metadata": {}, 318 | "outputs": [], 319 | "source": [ 320 | "q.draw()" 321 | ] 322 | }, 323 | { 324 | "cell_type": "code", 325 | "execution_count": null, 326 | "metadata": {}, 327 | "outputs": [], 328 | "source": [ 329 | "q.dequeue()" 330 | ] 331 | }, 332 | { 333 | "cell_type": "code", 334 | "execution_count": null, 335 | "metadata": {}, 336 | "outputs": [], 337 | "source": [ 338 | "q.enqueue()" 339 | ] 340 | }, 341 | { 342 | "cell_type": "code", 343 | "execution_count": null, 344 | "metadata": {}, 345 | "outputs": [], 346 | "source": [ 347 | "for i in range(100,104):\n", 348 | " q.enqueue(i)\n", 349 | "q.draw()" 350 | ] 351 | }, 352 | { 353 | "cell_type": "code", 354 | "execution_count": null, 355 | "metadata": {}, 356 | "outputs": [], 357 | "source": [ 358 | "for i in range(100,103):\n", 359 | " q.dequeue()\n", 360 | "q.draw()" 361 | ] 362 | }, 363 | { 364 | "cell_type": "code", 365 | "execution_count": null, 366 | "metadata": {}, 367 | "outputs": [], 368 | "source": [] 369 | }, 370 | { 371 | "cell_type": "markdown", 372 | "metadata": {}, 373 | "source": [ 374 | "## Binary Tree" 375 | ] 376 | }, 377 | { 378 | "cell_type": "code", 379 | "execution_count": 51, 380 | "metadata": {}, 381 | "outputs": [], 382 | "source": [ 383 | "class Node(object):\n", 384 | " def __init__(self,data=None):\n", 385 | " self.left = None\n", 386 | " self.right = None\n", 387 | " self.data = data\n", 388 | " \n", 389 | " def printNode(self):\n", 390 | " print(self.data)\n", 391 | " \n", 392 | " def insert(self, data):\n", 393 | " if self.data:\n", 394 | " if data < self.data:\n", 395 | " if self.left is None:\n", 396 | " self.left = Node(data)\n", 397 | " else:\n", 398 | " self.left.insert(data)\n", 399 | " elif data > self.data:\n", 400 | " if self.right is None:\n", 401 | " self.right = Node(data)\n", 402 | " else:\n", 403 | " self.right.insert(data)\n", 404 | " else:\n", 405 | " self.data = data\n", 406 | " \n", 407 | " def PrintTree(self):\n", 408 | " if self.left:\n", 409 | " self.left.PrintTree()\n", 410 | " print( self.data),\n", 411 | " if self.right:\n", 412 | " self.right.PrintTree()" 413 | ] 414 | }, 415 | { 416 | "cell_type": "code", 417 | "execution_count": 52, 418 | "metadata": {}, 419 | "outputs": [], 420 | "source": [ 421 | "bst=Node(10)" 422 | ] 423 | }, 424 | { 425 | "cell_type": "code", 426 | "execution_count": 53, 427 | "metadata": {}, 428 | "outputs": [ 429 | { 430 | "data": { 431 | "text/plain": [ 432 | "<__main__.Node at 0x1658c0b9198>" 433 | ] 434 | }, 435 | "execution_count": 53, 436 | "metadata": {}, 437 | "output_type": "execute_result" 438 | } 439 | ], 440 | "source": [ 441 | "bst" 442 | ] 443 | }, 444 | { 445 | "cell_type": "code", 446 | "execution_count": 54, 447 | "metadata": {}, 448 | "outputs": [ 449 | { 450 | "name": "stdout", 451 | "output_type": "stream", 452 | "text": [ 453 | "10\n" 454 | ] 455 | } 456 | ], 457 | "source": [ 458 | "bst.printNode()" 459 | ] 460 | }, 461 | { 462 | "cell_type": "code", 463 | "execution_count": 55, 464 | "metadata": {}, 465 | "outputs": [], 466 | "source": [ 467 | "bst.insert(6)" 468 | ] 469 | }, 470 | { 471 | "cell_type": "code", 472 | "execution_count": 56, 473 | "metadata": {}, 474 | "outputs": [ 475 | { 476 | "data": { 477 | "text/plain": [ 478 | "6" 479 | ] 480 | }, 481 | "execution_count": 56, 482 | "metadata": {}, 483 | "output_type": "execute_result" 484 | } 485 | ], 486 | "source": [ 487 | "bst.left.data" 488 | ] 489 | }, 490 | { 491 | "cell_type": "code", 492 | "execution_count": 57, 493 | "metadata": {}, 494 | "outputs": [], 495 | "source": [ 496 | "bst.insert(2)" 497 | ] 498 | }, 499 | { 500 | "cell_type": "code", 501 | "execution_count": 58, 502 | "metadata": {}, 503 | "outputs": [ 504 | { 505 | "name": "stdout", 506 | "output_type": "stream", 507 | "text": [ 508 | "2\n", 509 | "6\n", 510 | "10\n" 511 | ] 512 | } 513 | ], 514 | "source": [ 515 | "bst.PrintTree()" 516 | ] 517 | }, 518 | { 519 | "cell_type": "code", 520 | "execution_count": null, 521 | "metadata": {}, 522 | "outputs": [], 523 | "source": [] 524 | }, 525 | { 526 | "cell_type": "code", 527 | "execution_count": null, 528 | "metadata": {}, 529 | "outputs": [], 530 | "source": [] 531 | } 532 | ], 533 | "metadata": { 534 | "kernelspec": { 535 | "display_name": "Python 3", 536 | "language": "python", 537 | "name": "python3" 538 | }, 539 | "language_info": { 540 | "codemirror_mode": { 541 | "name": "ipython", 542 | "version": 3 543 | }, 544 | "file_extension": ".py", 545 | "mimetype": "text/x-python", 546 | "name": "python", 547 | "nbconvert_exporter": "python", 548 | "pygments_lexer": "ipython3", 549 | "version": "3.6.2" 550 | }, 551 | "latex_envs": { 552 | "LaTeX_envs_menu_present": true, 553 | "autoclose": false, 554 | "autocomplete": true, 555 | "bibliofile": "biblio.bib", 556 | "cite_by": "apalike", 557 | "current_citInitial": 1, 558 | "eqLabelWithNumbers": true, 559 | "eqNumInitial": 1, 560 | "hotkeys": { 561 | "equation": "Ctrl-E", 562 | "itemize": "Ctrl-I" 563 | }, 564 | "labels_anchors": false, 565 | "latex_user_defs": false, 566 | "report_style_numbering": false, 567 | "user_envs_cfg": false 568 | } 569 | }, 570 | "nbformat": 4, 571 | "nbformat_minor": 2 572 | } 573 | -------------------------------------------------------------------------------- /.ipynb_checkpoints/Vaccum_cleaner-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [], 3 | "metadata": {}, 4 | "nbformat": 4, 5 | "nbformat_minor": 2 6 | } 7 | -------------------------------------------------------------------------------- /Algorithms/Bubble_sort.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Fri Dec 22 17:45:47 2017 4 | @author: Tirthajyoti Sarkar 5 | Simple Bubble sort with counter for number of swap operations 6 | Accepts user input on minimum and maximum bound of the array and the size of the array 7 | """ 8 | 9 | import random 10 | 11 | def bubble_sort(array): 12 | n = len(array) 13 | # Set a swap counter to a non-zero value 14 | swap_counter=-1 15 | swap_op=0 16 | # Unitll swap counter hits zero... 17 | while(swap_counter!=0): 18 | # Reset the swap counter at the beginnig of each iteration 19 | swap_counter=0 20 | # Iterate over the array examining the a pair of data 21 | for i in range(n-1): 22 | if(array[i]>array[i+1]): 23 | temp=array[i] 24 | array[i]=array[i+1] 25 | array[i+1]=temp 26 | # Print for troubleshooting 27 | #print(sorted_array) 28 | swap_counter+=1 29 | swap_op+=1 30 | else: 31 | pass 32 | return (array,swap_op) 33 | 34 | # User inputs for generating the random arrays 35 | mini = int(input("Enter the minimum bound:")) 36 | maxi = int(input("Enter the maximum bound:")) 37 | num = int(input("Enter the size:")) 38 | 39 | # Create random array based on user-specified minimum/maximum bounds and number of elements 40 | a= [] 41 | for i in range(num): 42 | a.append(random.randint(mini,maxi)) 43 | 44 | print("\nInitial array:",a) 45 | 46 | # Get the sorted array back along with the count of # of operations it took to sort 47 | sorted_array,n_op=bubble_sort(a) 48 | print("Sorted array: {}\nTook {} operations".format(sorted_array,n_op)) -------------------------------------------------------------------------------- /Algorithms/Count_inversion.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Thu Jan 25 21:16:36 2018 4 | 5 | @author: Tirtha 6 | """ 7 | 8 | def merge_count_SplitInv(L1,L2): 9 | result=[] 10 | count=0 11 | # This loop runs till both input lists have non-zero elements in them 12 | # That means this loop stops when either of the input list runs out of element 13 | while (len(L1)>0 and len(L2)>0): 14 | if L1[0]<=L2[0]: 15 | # Append to the result list 16 | result.append(L1[0]) 17 | #print("Result:",result) 18 | # Pop the first element of the list 19 | L1.pop(0) 20 | else: 21 | # Append to the result list 22 | result.append(L2[0]) 23 | #print("Result:",result) 24 | # Pop the first element of the list 25 | L2.pop(0) 26 | # CRUX OF THE ALGORITHM: When we copy over from L2, we increment 27 | #count by the number of elements REMAINING in L1 i.e. length of L1 because 28 | # the length is dynamically modified by popping the first element out whenever 29 | # we copy over from L1 30 | count+=len(L1) 31 | # Now checking which input list has run out of element. 32 | # Whichever list still has element left, append all of them to the result array 33 | # Note, only one of these if-loops will be executed 34 | if(len(L1)>0): 35 | result=result+L1 36 | if(len(L2)>0): 37 | result=result+L2 38 | 39 | return (result,count) 40 | 41 | def sort_count_inversion(my_list): 42 | length=len(my_list) 43 | # Base case 44 | if length==1: 45 | return (my_list,0) 46 | # Recursive case 47 | else: 48 | l1_sorted,x=sort_count_inversion(my_list[0:int(length/2)]) 49 | l2_sorted,y=sort_count_inversion(my_list[int(length/2):length]) 50 | l_sorted,z=merge_count_SplitInv(l1_sorted,l2_sorted) 51 | return (l_sorted,(x+y+z)) -------------------------------------------------------------------------------- /Algorithms/Dselect.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Sun Jan 28 12:30:03 2018 4 | 5 | @author: Tirtha 6 | """ 7 | import random 8 | 9 | def partition(A,p_idx): 10 | p=A[p_idx] 11 | #print("Input list to partition with pivot {}: {}".format(p,A)) 12 | # Swap/move pivot to leftmost 13 | temp=A[0] 14 | A[0]=A[p_idx] 15 | A[p_idx]=temp 16 | 17 | l=0 18 | i=l+1 19 | r=len(A) 20 | for j in range(l+1,r): 21 | if A[j]<=p: 22 | temp=A[j] 23 | A[j]=A[i] 24 | A[i]=temp 25 | i+=1 26 | # Now swap the pivot from the 0-th index to its rightful index 27 | temp=A[i-1] 28 | A[i-1]=A[l] 29 | A[l]=temp 30 | # Print partitioned list and new pivot index for debugging 31 | #print("Partitioned list:",A) 32 | #print("New pivot",i-1) 33 | #print("") 34 | return (i-1) 35 | 36 | def median(A): 37 | if len(A)==1: 38 | return A[0] 39 | elif len(A)==2: 40 | return A[1] 41 | else: 42 | return A[int(len(A)/2)] 43 | 44 | def Dselect(my_list,n): 45 | length=len(my_list) 46 | # Base case 47 | if length==1: 48 | return my_list[0] 49 | # Recursive case 50 | else: 51 | chunk=5 52 | medians=[] 53 | A=[] 54 | for i in range(0, length, chunk): 55 | A.append(my_list[i:i + chunk]) 56 | #print("A:",A) 57 | for array in A: 58 | array.sort() 59 | medians.append(median(array)) 60 | # Sorts the medians and choose the 'median of the medians' as pivot 61 | medians.sort() 62 | #print("Medians sorted:",medians) 63 | p = Dselect(medians,int(length/10)) 64 | p_idx=my_list.index(p) 65 | #print("Pivot index and pivots:{}, {}".format(p_idx,p)) 66 | # Partition based on the chosen median of median pivot 67 | new_pivot = partition(my_list,p_idx) 68 | # Case to check if the new pivot returned by partition is the n-th order 69 | # Disabled because it was giving error on some cases and preventing the code to reach the base case 70 | #if new_pivot==n: 71 | #print("New pivot equal to sought order") 72 | #return (my_list[new_pivot-1]) 73 | if new_pivot>=n: 74 | # Recurse on the left side of the array with unchanged order statistic 75 | left=my_list[0:new_pivot] 76 | #print("New pivot {} >= {}. Recursing on {} with order {}".format(new_pivot,n,left,n)) 77 | return Dselect(left,n) 78 | else: 79 | # Recurse on the right side of the array with order statistic shrinked 80 | right=my_list[new_pivot:] 81 | #print("New pivot {} < {}. Recursing on {} with order changed to {}".format(new_pivot,n,right,n-new_pivot)) 82 | return Dselect(right,n-new_pivot) 83 | 84 | """ 85 | # Test code for single case with fixed order statistic 86 | ##============= 87 | N_test=20 88 | test_lst=[] 89 | for i in range(N_test): 90 | test_lst.append(random.randint(0,100)) 91 | #n= random.randint(1,6) 92 | n=5 93 | print("Original list:",test_lst) 94 | print("Order statistic sought",n) 95 | print("") 96 | 97 | result = Dselect(test_lst,n) 98 | test_lst.sort() 99 | #element = test_lst[result-1] 100 | print("{}-th order statistic is {}".format(n,result)) 101 | 102 | print("Sorted list",test_lst) 103 | """ 104 | 105 | ## Test code with 100 cases with random order statistic 106 | N=10000 107 | check = [] 108 | # Create a test array of 20 integers 109 | for i in range(N): 110 | N_test=20 111 | test_lst=[] 112 | for i in range(N_test): 113 | test_lst.append(random.randint(0,100)) 114 | # Picking a random test input for order statistic 115 | n= random.randint(1,20) 116 | result = Dselect(test_lst,n) 117 | # Call Python's built-in sort method on the test array 118 | test_lst.sort() 119 | # Check if the sorted array's n-1-th element is the n-th order statistic returned by our program 120 | check.append(test_lst[n-1]==result) 121 | # Print the sum total of truth values in the check array 122 | print(sum(check)) 123 | 124 | -------------------------------------------------------------------------------- /Algorithms/Insertion_sort.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Fri Dec 22 23:26:32 2017 4 | @author: Tirthajyoti Sarkar 5 | Simple Insertion sort with counter for total number of operations (shifting and iterating) 6 | Accepts user input on minimum and maximum bound of the array and the size of the array 7 | """ 8 | import random 9 | 10 | def insertion_sort(array): 11 | counter = 0 12 | # Iterate over the array starting from 2nd element i.e. index 1 13 | for index in range(1,len(array)): 14 | # Set current value and index 15 | currentvalue = array[index] 16 | position = index 17 | # Keep shifting the elements to insert the next unsorted element in the proper position 18 | while position>0 and array[position-1]>currentvalue: 19 | array[position]=array[position-1] 20 | position = position-1 21 | array[position]=currentvalue 22 | counter+=1 23 | # Print current state of array for troubleshooting 24 | #print(array) 25 | return (array,counter) 26 | 27 | # User inputs for generating the random arrays 28 | mini = int(input("Enter the minimum bound:")) 29 | maxi = int(input("Enter the maximum bound:")) 30 | num = int(input("Enter the size:")) 31 | 32 | # Create random array based on user-specified minimum/maximum bounds and number of elements 33 | a= [] 34 | for i in range(num): 35 | a.append(random.randint(mini,maxi)) 36 | 37 | print("\nInitial array:",a) 38 | 39 | # Get the sorted array back along with the count of # of operations it took to sort 40 | sorted_array,n_op=insertion_sort(a) 41 | print("Sorted array: {}\nTook {} operations".format(sorted_array,n_op)) -------------------------------------------------------------------------------- /Algorithms/MergeSort.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Wed Jan 24 22:42:19 2018 4 | 5 | @author: Tirtha 6 | """ 7 | def merge(list1,list2): 8 | """ 9 | Takes two lists and merge them in a sorted list 10 | """ 11 | # Initialie the empty list 12 | result=[] 13 | i=0 14 | j=0 15 | # This loop runs till both input lists have non-zero elements in them 16 | # That means this loop stops when either of the input list runs out of element 17 | while (len(list1)>0 and len(list2)>0): 18 | if list1[0]<=list2[0]: 19 | # Append to the result list 20 | result.append(list1[0]) 21 | #print("Result:",result) 22 | # Pop the first element of the list 23 | list1.pop(0) 24 | i=i+1 25 | else: 26 | # Append to the result list 27 | result.append(list2[0]) 28 | #print("Result:",result) 29 | # Pop the first element of the list 30 | list2.pop(0) 31 | j+=1 32 | # Now checking which input list has run out of element. 33 | # Whichever list still has element left, append all of them to the result array 34 | # Note, only one of these if-loops will be executed 35 | if(len(list1)>0): 36 | result=result+list1 37 | if(len(list2)>0): 38 | result=result+list2 39 | print("Result:",result) 40 | #print(f"i:{i},j:{j}") 41 | return (result) 42 | 43 | def mergeSort(my_list): 44 | n = len(my_list) 45 | # Base case for 1-element array 46 | if n==1: 47 | return (my_list) 48 | # Recursive case: 49 | # Divide the array into two halves. 50 | # Mergesort on the left half 51 | # Mergesort on the right half 52 | # Merge two sorted arrays 53 | # Return the merged result 54 | else: 55 | left_half=my_list[0:int(n/2)] 56 | right_half=my_list[int(n/2):n] 57 | print("Left half:",left_half) 58 | print("Right half:",right_half) 59 | left=mergeSort(left_half) 60 | right=mergeSort(right_half) 61 | print(f"Merging {left} and {right}") 62 | sorted_list=merge(left,right) 63 | return (sorted_list) -------------------------------------------------------------------------------- /Algorithms/QuickSelect-1.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Sun Jan 28 16:17:46 2018 4 | 5 | @author: Tirtha 6 | """ 7 | 8 | import random 9 | 10 | def Rselect(my_list,n): 11 | length=len(my_list) 12 | if length==1: 13 | return my_list[0] 14 | else: 15 | low=[] 16 | high=[] 17 | p_idx = random.randint(1,length-1) 18 | pivot = my_list[p_idx] 19 | #print("Pivot chosen",pivot) 20 | if pivot==max(my_list): 21 | high.append(pivot) 22 | my_list.remove(pivot) 23 | low=my_list 24 | else: 25 | for ele in my_list: 26 | if ele<=pivot: 27 | low.append(ele) 28 | else: 29 | high.append(ele) 30 | #low=low+equal 31 | #print("Low list",low) 32 | #print("High list",high) 33 | if n<=len(low): 34 | #print("Recursing on {} with order {}".format(low,n)) 35 | return Rselect(low,n) 36 | else: 37 | #print("Recursing on {} with order {}".format(high,n-len(low))) 38 | return Rselect(high,n-len(low)) 39 | 40 | 41 | # Test code for single case with fixed order statistic 42 | ##============= 43 | """ 44 | N_test=7 45 | test_lst=[] 46 | for i in range(N_test): 47 | test_lst.append(random.randint(0,100)) 48 | #n= random.randint(1,6) 49 | n=3 50 | print("Original list:",test_lst) 51 | print("Order statistic sought",n) 52 | print("") 53 | 54 | result = Rselect(test_lst,n) 55 | test_lst.sort() 56 | #element = test_lst[result-1] 57 | print("{}-th order statistic is {}".format(n,result)) 58 | 59 | print("Sorted list",test_lst) 60 | 61 | """ 62 | ## Test code with 100 cases with random order statistic 63 | N=1000 64 | check = [] 65 | # Create a test array of 20 integers 66 | for i in range(N): 67 | N_test=20 68 | test_lst=[] 69 | for i in range(N_test): 70 | test_lst.append(random.randint(0,100)) 71 | # Picking a random test input for order statistic 72 | n= random.randint(0,19) 73 | result = Rselect(test_lst,n) 74 | # Call Python's built-in sort method on the test array 75 | test_lst.sort() 76 | # Check if the sorted array's n-1-th element is the n-th order statistic returned by our program 77 | check.append(test_lst[n-1]==result) 78 | # Print the sum total of truth values in the check array 79 | print(sum(check)) -------------------------------------------------------------------------------- /Algorithms/Quicksort-1.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Fri Jan 26 18:26:21 2018 4 | 5 | @author: Tirtha 6 | """ 7 | import random 8 | 9 | def quicksort(lst): 10 | #count_op=0 11 | smaller=[] 12 | equal=[] 13 | bigger=[] 14 | if len(lst)==0 or len(lst)==1: 15 | return (lst) 16 | else: 17 | pivot=lst[0] 18 | for n in lst: 19 | if n start: 10 | pivot = array[start] 11 | middle = start + 1 12 | for i in range(start+1, end): 13 | if array[i] > array[middle]: 14 | tmp = array[i] 15 | array[i] = array[middle] 16 | array[middle] = tmp 17 | middle += 1 18 | sort(array, start, middle) 19 | sort(array, middle, end) 20 | 21 | N_test=10 22 | test_lst=[] 23 | for i in range(N_test): 24 | test_lst.append(random.randint(0,100)) 25 | 26 | print("Original list:",test_lst) 27 | sort(test_lst,0,9) 28 | print("Sorted list:",test_lst) -------------------------------------------------------------------------------- /Algorithms/Quicksort_InPlac2.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Fri Jan 26 18:32:13 2018 4 | 5 | @author: Tirtha 6 | """ 7 | 8 | import random 9 | 10 | def partition(A,l,r): 11 | p=A[l] 12 | i=l+1 13 | for j in range(l+1,r): 14 | if A[j]<=p: 15 | temp=A[j] 16 | A[j]=A[i] 17 | A[i]=temp 18 | i+=1 19 | temp=A[i-1] 20 | A[i-1]=A[l] 21 | A[l]=temp 22 | print("Modified list:",A) 23 | print("Pivot pos",i) 24 | return (i) 25 | 26 | def QuickSortInPlace(lst,low,high): 27 | #count_op=0 28 | length=high-low 29 | # Base case: Nothing to do 30 | if length<=1: 31 | pass 32 | elif length==2: 33 | if (lst[0]>=lst[1]): 34 | temp=lst[0] 35 | lst[0]=lst[1] 36 | lst[1]=temp 37 | # Recursive case 38 | else: 39 | # Partition the array and get back the pivot position 40 | pivot_pos=partition(lst,low,high) 41 | # Quicksort on the left half of the pivot 42 | QuickSortInPlace(lst,low,pivot_pos-1) 43 | # Quicksort on the right half of the pivot 44 | QuickSortInPlace(lst,pivot_pos,high) 45 | 46 | # Test code 47 | ##============= 48 | N_test=15 49 | test_lst=[] 50 | for i in range(N_test): 51 | test_lst.append(random.randint(0,100)) 52 | 53 | print("Original list:",test_lst) 54 | QuickSortInPlace(test_lst,0,15) 55 | print("Sorted list: ",test_lst) -------------------------------------------------------------------------------- /Algorithms/Quicksort_InPlace.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Fri Jan 26 18:32:13 2018 4 | 5 | @author: Tirtha 6 | """ 7 | 8 | import random 9 | import math 10 | 11 | def partition(A,l,r): 12 | global count_op 13 | p=A[l] 14 | i=l+1 15 | for j in range(l+1,r): 16 | if A[j]<=p: 17 | temp=A[j] 18 | A[j]=A[i] 19 | A[i]=temp 20 | i+=1 21 | count_op+=4 22 | temp=A[i-1] 23 | A[i-1]=A[l] 24 | A[l]=temp 25 | print("Modified list:",A) 26 | #print("Pivot pos",i) 27 | return (i) 28 | 29 | def QuickSortInPlace(lst,low,high): 30 | global count_op 31 | length=high-low 32 | # Base case: Nothing to do 33 | if length<=1: 34 | pass 35 | # Recursive case 36 | else: 37 | # Partition the array and get back the pivot position 38 | pivot_pos=partition(lst,low,high) 39 | # Quicksort on the left half of the pivot 40 | QuickSortInPlace(lst,low,pivot_pos-1) 41 | # Quicksort on the right half of the pivot 42 | QuickSortInPlace(lst,pivot_pos,high) 43 | 44 | # Test code 45 | ##============= 46 | 47 | N_test=15 48 | test_lst=[] 49 | for i in range(N_test): 50 | test_lst.append(random.randint(0,100)) 51 | 52 | print("Original list:",test_lst) 53 | QuickSortInPlace(test_lst,0,15) 54 | print("Sorted list: ",test_lst) 55 | 56 | """ 57 | count_array=[] 58 | log_array=[] 59 | for i in range(2,102): 60 | test_lst=[] 61 | count_op=0 62 | for k in range(i): 63 | test_lst.append(random.randint(0,1000)) 64 | QuickSortInPlace(test_lst,0,i) 65 | count_array.append(count_op) 66 | log_array.append(5*i*math.log(i,2)) 67 | 68 | print(count_array) 69 | 70 | import matplotlib.pyplot as plt 71 | plt.scatter(range(2,102),count_array) 72 | plt.plot(range(2,102),log_array,lw=3,color='red') 73 | plt.grid(True) 74 | plt.show() 75 | """ -------------------------------------------------------------------------------- /Algorithms/Random_Select_InPlace.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Sun Jan 28 12:30:03 2018 4 | 5 | @author: Tirtha 6 | """ 7 | import random 8 | 9 | def partition(A,p_idx): 10 | p=A[p_idx] 11 | #print("Input list to partition with pivot {}: {}".format(p,A)) 12 | # Swap/move pivot to leftmost 13 | temp=A[0] 14 | A[0]=A[p_idx] 15 | A[p_idx]=temp 16 | 17 | l=0 18 | i=l+1 19 | r=len(A) 20 | for j in range(l+1,r): 21 | if A[j]<=p: 22 | temp=A[j] 23 | A[j]=A[i] 24 | A[i]=temp 25 | i+=1 26 | # Now swap the pivot from the 0-th index to its rightful index 27 | temp=A[i-1] 28 | A[i-1]=A[l] 29 | A[l]=temp 30 | # Print partitioned list and new pivot index for debugging 31 | #print("Partitioned list:",A) 32 | #print("New pivot",i-1) 33 | #print("") 34 | return (i-1) 35 | 36 | 37 | def Rselect(my_list,n): 38 | length=len(my_list) 39 | # Base case 40 | if length==1: 41 | return my_list[0] 42 | # Recursive case 43 | else: 44 | # Randomly choose a pivot index from 1 to length-1 45 | p_idx = random.randint(1,length-1) 46 | #print("Pivot index chosen",p_idx) 47 | # Partition based on the randomly chosen index 48 | new_pivot = partition(my_list,p_idx) 49 | # Case to check if the new pivot returned by partition is the n-th order 50 | # Disabled because it was giving error on some cases and preventing the code to reach the base case 51 | #if new_pivot==n: 52 | #print("New pivot equal to sought order") 53 | #return (my_list[new_pivot-1]) 54 | if new_pivot>=n: 55 | # Recurse on the left side of the array with unchanged order statistic 56 | left=my_list[0:new_pivot] 57 | #print("New pivot {} >= {}. Recursing on {} with order {}".format(new_pivot,n,left,n)) 58 | return Rselect(left,n) 59 | else: 60 | # Recurse on the right side of the array with order statistic shrinked 61 | right=my_list[new_pivot:] 62 | #print("New pivot {} < {}. Recursing on {} with order changed to {}".format(new_pivot,n,right,n-new_pivot)) 63 | return Rselect(right,n-new_pivot) 64 | 65 | """ 66 | # Test code for single case with fixed order statistic 67 | ##============= 68 | N_test=7 69 | test_lst=[] 70 | for i in range(N_test): 71 | test_lst.append(random.randint(0,100)) 72 | #n= random.randint(1,6) 73 | n=3 74 | print("Original list:",test_lst) 75 | print("Order statistic sought",n) 76 | print("") 77 | 78 | result = Rselect(test_lst,n) 79 | test_lst.sort() 80 | #element = test_lst[result-1] 81 | print("{}-th order statistic is {}".format(n,result)) 82 | 83 | print("Sorted list",test_lst) 84 | """ 85 | 86 | ## Test code with 100 cases with random order statistic 87 | N=10000 88 | check = [] 89 | # Create a test array of 20 integers 90 | for i in range(N): 91 | N_test=20 92 | test_lst=[] 93 | for i in range(N_test): 94 | test_lst.append(random.randint(0,100)) 95 | # Picking a random test input for order statistic 96 | n= random.randint(1,20) 97 | result = Rselect(test_lst,n) 98 | # Call Python's built-in sort method on the test array 99 | test_lst.sort() 100 | # Check if the sorted array's n-1-th element is the n-th order statistic returned by our program 101 | check.append(test_lst[n-1]==result) 102 | # Print the sum total of truth values in the check array 103 | print(sum(check)) 104 | 105 | -------------------------------------------------------------------------------- /Algorithms/Selection_sort.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Fri Dec 22 18:44:02 2017 4 | @author: Tirthajyoti Sarkar 5 | Simple Selection sort with counter for total number of operations (finding minimum and swapping) 6 | Accepts user input on minimum and maximum bound of the array and the size of the array 7 | """ 8 | import random 9 | 10 | def find_min(array): 11 | n=len(array) 12 | r = array[0] 13 | count=0 14 | for i in range(1,n): 15 | count+=1 16 | if r>array[i]: 17 | r=array[i] 18 | return(r,count) 19 | 20 | def selection_sort(array): 21 | n=len(array) 22 | num_op=0 23 | # Iterate over the length of the array, pushing smaller values to the left 24 | for i in range(n): 25 | # Scan the array from i-th element (where the iterator is currently) to the end for minimum 26 | m,c_min=find_min(array[i:n]) 27 | # IMPORTANT: Get the index of the minimum element w.r.t. to the main array 28 | m_index=array[i:n].index(m)+i 29 | # If the first element of the unsorted portion i.e. i-th element> minimum, then SWAP 30 | if (array[i]>m): 31 | # Print statement for examining minimum and its index, Troubleshooting 32 | #print("Minimum found {} at position {}. Swapping positions {} and {}".format(m,m_index,i,m_index)) 33 | temp=array[i] 34 | array[i]=m 35 | array[m_index]=temp 36 | num_op+=(c_min+1) 37 | print(array) 38 | else: 39 | pass 40 | return (array,num_op) 41 | 42 | # User inputs for generating the random arrays 43 | mini = int(input("Enter the minimum bound:")) 44 | maxi = int(input("Enter the maximum bound:")) 45 | num = int(input("Enter the size:")) 46 | 47 | # Create random array based on user-specified minimum/maximum bounds and number of elements 48 | a= [] 49 | for i in range(num): 50 | a.append(random.randint(mini,maxi)) 51 | 52 | print("\nInitial array:",a) 53 | 54 | # Get the sorted array back along with the count of # of operations it took to sort 55 | sorted_array,n_op=selection_sort(a) 56 | print("Sorted array: {}\nTook {} operations".format(sorted_array,n_op)) -------------------------------------------------------------------------------- /Data Structures/Common_data_structures_class.py: -------------------------------------------------------------------------------- 1 | """ 2 | Created on Wed Jan 24 19:21:12 2018 3 | @author: Tirtha 4 | """ 5 | 6 | class Stack: 7 | """ 8 | Stack data structure using list 9 | """ 10 | def __init__(self,value): 11 | """ 12 | Class initializer: Produces a stack with a single value or a list of values 13 | """ 14 | self._items = [] 15 | if type(value)==list: 16 | for v in value: 17 | self._items.append(v) 18 | self._height = len(value) 19 | else: 20 | self._items.append(value) 21 | self._height = 1 22 | 23 | def pop(self): 24 | if self._height == 0: 25 | print ("Stack is empty. Nothing to pop.") 26 | return None 27 | else: 28 | self._height -=1 29 | return self._items.pop() 30 | 31 | def push(self,value): 32 | self._height +=1 33 | self._items.append(value) 34 | 35 | def isEmpty(self): 36 | return self._height==0 37 | 38 | def draw(self): 39 | if self.isEmpty(): 40 | pass 41 | return None 42 | else: 43 | n=self._height 44 | print('['+str(self._items[n-1])+']') 45 | for i in range(n-2,-1,-1): 46 | print(" | ") 47 | print('['+str(self._items[i])+']') 48 | 49 | ###============================================================================================== 50 | 51 | class Queue: 52 | """ 53 | Queue data structure using list 54 | """ 55 | def __init__(self,value): 56 | """ 57 | Class initializer: Produces a queue with a single value or a list of values 58 | """ 59 | self._items = [] 60 | if type(value)==list: 61 | for v in value: 62 | self._items.append(v) 63 | self._length = len(value) 64 | else: 65 | self._items.append(value) 66 | self._length = 1 67 | 68 | def dequeue(self): 69 | if self._length == 0: 70 | print ("Queue is empty. Nothing to dequeue.") 71 | return None 72 | else: 73 | self._length -=1 74 | return self._items.pop(0) 75 | 76 | def enqueue(self,value): 77 | self._length +=1 78 | self._items.append(value) 79 | 80 | def isEmpty(self): 81 | return self._length==0 82 | 83 | def draw(self): 84 | if self.isEmpty(): 85 | pass 86 | return None 87 | else: 88 | n=self._length 89 | for i in range(n-1): 90 | print('['+str(self._items[i])+']-',end='') 91 | print('['+str(self._items[n-1])+']') 92 | 93 | ###================================================================================= 94 | 95 | class Tree: 96 | """ 97 | Recursive definition of Tree class plus various helper functions/methods 98 | """ 99 | def __init__(self, value, children): 100 | """ 101 | Class initializer: Produces a single root node having a specific string value; 102 | children is a list of references to the root of the children branches. 103 | Note th children are trees themselves, hence the recursion. 104 | """ 105 | self._value = value 106 | self._children = children 107 | 108 | def strep(self): 109 | """ 110 | Generates a string representation of the tree 111 | """ 112 | text = "" 113 | text+=str(self._value) 114 | 115 | for child in self._children: 116 | text+='[' 117 | text+=child.strep() 118 | text+=']' 119 | return text 120 | 121 | def get_value(self): 122 | return self._value 123 | 124 | def children(self): 125 | for child in self._children: 126 | yield child 127 | 128 | def num_nodes(self): 129 | result = 1 130 | for child in self._children: 131 | result+=child.num_nodes() 132 | return result 133 | 134 | def num_leaves(self): 135 | if len(self._children)==0: 136 | return 1 137 | else: 138 | result=0 139 | for child in self._children: 140 | result += child.num_leaves() 141 | return result 142 | 143 | def height(self): 144 | height=0 145 | for child in self._children: 146 | height = max(height,child.height()+1) 147 | return height 148 | 149 | ###================================================================================ 150 | 151 | class Arithmatic (Tree): 152 | 153 | def __init__(self, value, children): 154 | Tree.__init__(self, value, children) 155 | 156 | def strexp(self): 157 | if len(self._children)==0: 158 | return str(self._value) 159 | else: 160 | text='(' 161 | text+=self._children[0].strexp() 162 | text+=str(self._value) 163 | text+=self._children[1].strexp() 164 | text+=')' 165 | return text 166 | 167 | def evaluate_exp(self): 168 | if len(self._children)==0: 169 | if ('.' in self._value): 170 | return float(self._value) 171 | else: 172 | return int(self._value) 173 | else: 174 | function = self._value 175 | left_value = self._children[0].evaluate_exp() 176 | right_value = self._children[1].evaluate_exp() 177 | if function=='+': 178 | return left_value+right_value 179 | if function=='-': 180 | return left_value-right_value 181 | if function=='*': 182 | return left_value*right_value 183 | if function=='/': 184 | return left_value/right_value 185 | if function=='%': 186 | return left_value%right_value 187 | if function=='^': 188 | return left_value**right_value 189 | -------------------------------------------------------------------------------- /Data Structures/Common_data_structures_test.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Wed Jan 24 21:26:42 2018 4 | @author: Tirtha 5 | """ 6 | 7 | from Common_data_structures_class import Stack, Queue, Tree, Arithmatic 8 | 9 | ###Test code for Stack 10 | ###====================================================== 11 | init_list=[11,22,33,44] 12 | print("Initializing stack with a list:",init_list) 13 | s1 = Stack(init_list) 14 | s1.draw() 15 | print("height of the stack:",s1._height) 16 | print("Popping the top of the stack:",s1.pop()) 17 | print("height of the stack now:",s1._height) 18 | print("Pushing 20...") 19 | s1.push(20) 20 | print("Pushing 30...") 21 | s1.push(30) 22 | s1.draw() 23 | print("height of the stack now:",s1._height) 24 | print("Popping the top of the stack:",s1.pop()) 25 | print("Height now:",s1._height) 26 | print("Popping the top of the stack:",s1.pop()) 27 | print("Height now:",s1._height) 28 | print("Popping the top of the stack:",s1.pop()) 29 | print("Height now:",s1._height) 30 | print("Popping the top of the stack:",s1.pop()) 31 | print("Height now:",s1._height) 32 | print("Popping the top of the stack:",s1.pop()) 33 | print("Height now:",s1._height) 34 | print("Popping the top of the stack:",s1.pop()) 35 | print("Height now:",s1._height) 36 | print("Is the stack empty?",s1.isEmpty()) 37 | print("Pushing a float") 38 | s1.push(3.56) 39 | print("Pushing a string") 40 | s1.push("Hello") 41 | s1.draw() 42 | print("Popping the top of the stack:",s1.pop()) 43 | print("Popping the top of the stack:",s1.pop()) 44 | print("Is the stack empty?",s1.isEmpty()) 45 | 46 | ###Test code for Queue 47 | ###====================================================== 48 | init_list=[99,98,97,96] 49 | print("Initializing queue with a list:",init_list) 50 | q1 = Queue(init_list) 51 | q1.draw() 52 | print("Length of the queue:",q1._length) 53 | print("Dequeing from the queue:",q1.dequeue()) 54 | print("Length of the queue now:",q1._length) 55 | print("Enqueing 20...") 56 | q1.enqueue(20) 57 | print("Enqueing 30...") 58 | q1.enqueue(30) 59 | q1.draw() 60 | print("Length of the queue now:",q1._length) 61 | print("Dequeing from the queue:",q1.dequeue()) 62 | print("Length now:",q1._length) 63 | print("Dequeing from the queue:",q1.dequeue()) 64 | print("Length now:",q1._length) 65 | print("Dequeing from the queue:",q1.dequeue()) 66 | print("Length now:",q1._length) 67 | print("Dequeing from the queue:",q1.dequeue()) 68 | print("Length now:",q1._length) 69 | print("Dequeing from the queue:",q1.dequeue()) 70 | print("Length now:",q1._length) 71 | print("Dequeing from the queue:",q1.dequeue()) 72 | print("Length now:",q1._length) 73 | print("Is the queue empty?",q1.isEmpty()) 74 | print("Enqueing a float") 75 | q1.enqueue(3.56) 76 | print("Enqueing a string") 77 | q1.enqueue("Hello") 78 | q1.draw() 79 | print("Dequeing from the queue:",q1.dequeue()) 80 | print("Dequeing from the queue:",q1.dequeue()) 81 | print("Is the queue empty?",q1.isEmpty()) 82 | 83 | ###Test code for Tree 84 | ###====================================================== 85 | tree_a = Tree('a',[]) 86 | tree_b = Tree('b',[]) 87 | 88 | tree_cab = Tree('c',[tree_a,tree_b]) 89 | 90 | print (tree_a.strep()) 91 | print(tree_b.get_value()) 92 | print(tree_cab.strep()) 93 | 94 | tree_4 = Tree('d',[tree_cab,tree_b,tree_a]) 95 | print (tree_4.strep()) 96 | print(tree_4.num_nodes()) 97 | print(tree_4.num_leaves()) 98 | print(tree_4.height()) 99 | 100 | ###Test code for Arithmatic 101 | ###====================================================== 102 | #exp1=Arithmatic('*',[]) 103 | exp2=Arithmatic('1.2',[]) 104 | exp3=Arithmatic('5.2',[]) 105 | exp4=Arithmatic('*',[exp2,exp3]) 106 | exp5=Arithmatic('4.2',[]) 107 | exp6=Arithmatic('7.5',[]) 108 | exp7=Arithmatic('+',[exp5,exp6]) 109 | exp8=Arithmatic('/',[exp4,exp7]) 110 | exp9=Arithmatic('2',[]) 111 | exp10=Arithmatic('^',[exp9,exp8]) 112 | 113 | print("The expression is:",exp10.strexp()) 114 | print("The evluated value is:",exp10.evaluate_exp()) 115 | print("String representation is:",exp10.strep()) 116 | print("Depth of this computation graph tree is:",exp10.height()) -------------------------------------------------------------------------------- /Data Structures/Graph-1.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Thu Jun 14 20:55:21 2018 4 | 5 | @author: Tirtha 6 | """ 7 | 8 | class Node (object): 9 | def __init__(self,name): 10 | self.name=name 11 | 12 | def getName(self): 13 | return (self.name) 14 | 15 | def __str__(self): 16 | return (self.name) 17 | 18 | class Edge (object): 19 | def __init__(self,src,dest): 20 | self.src=src 21 | self.dest=dest 22 | 23 | def getSource(self): 24 | return (self.src) 25 | 26 | def getDest(self): 27 | return (self.dest) 28 | 29 | def __str__(self): 30 | return (self.src+"->"self.dest) 31 | -------------------------------------------------------------------------------- /Data Structures/Graph1.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Thu Jun 14 20:55:21 2018 4 | 5 | @author: Tirtha 6 | """ 7 | 8 | class Node (object): 9 | def __init__(self,name): 10 | self.name=name 11 | 12 | def getName(self): 13 | return (self.name) 14 | 15 | def __str__(self): 16 | return (self.name) 17 | 18 | class Edge (object): 19 | def __init__(self,src,dest): 20 | self.src=src 21 | self.dest=dest 22 | 23 | def getSource(self): 24 | return (self.src) 25 | 26 | def getDest(self): 27 | return (self.dest) 28 | 29 | def __str__(self): 30 | return (self.src.getName()+"->"+self.dest.getName()) 31 | 32 | class Digraph(object): 33 | def __init__(self): 34 | self.edges={} 35 | 36 | def addNode(self,node): 37 | if node in self.edges: 38 | raise ValueError("Duplicate node") 39 | else: 40 | self.edges[node]=[] 41 | 42 | def addEdge(self,edge): 43 | src=edge.getSource() 44 | dest=edge.getDest() 45 | if (src not in self.edges) and (dest not in self.edges): 46 | raise ValueError("Node not in graph") 47 | else: 48 | self.edges[src].append(dest) # Builds adjacency list 49 | 50 | def childrenOf(self,node): 51 | return self.edges[node] 52 | 53 | def hasNode(self,node): 54 | return node in self.edges 55 | 56 | def getNode(self,name): 57 | for n in self.edges: 58 | if n.getName()==name: 59 | return n 60 | raise NameError(name) 61 | 62 | def __str__(self): 63 | toPrint='' 64 | for src in self.edges: 65 | for dest in self.edges[src]: 66 | toPrint=toPrint+src.getName()+"->"+dest.getName()+"\n" 67 | 68 | if (toPrint==''): 69 | return ("Empty graph! Nothing to print") 70 | else: 71 | return toPrint[:-1] 72 | 73 | -------------------------------------------------------------------------------- /Data Structures/Graphs-1.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "### Class Node" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": {}, 14 | "outputs": [], 15 | "source": [ 16 | "class Node (object):\n", 17 | " def __init__(self,name):\n", 18 | " self.name=name\n", 19 | " \n", 20 | " def getName(self):\n", 21 | " return (self.name)\n", 22 | " \n", 23 | " def __str__(self):\n", 24 | " return (self.name)" 25 | ] 26 | }, 27 | { 28 | "cell_type": "markdown", 29 | "metadata": {}, 30 | "source": [ 31 | "### Class Edge" 32 | ] 33 | }, 34 | { 35 | "cell_type": "code", 36 | "execution_count": 2, 37 | "metadata": {}, 38 | "outputs": [], 39 | "source": [ 40 | "class Edge (object):\n", 41 | " def __init__(self,src,dest):\n", 42 | " self.src=src\n", 43 | " self.dest=dest\n", 44 | " \n", 45 | " def getSource(self):\n", 46 | " return (self.src)\n", 47 | " \n", 48 | " def getDest(self):\n", 49 | " return (self.dest)\n", 50 | " \n", 51 | " def __str__(self):\n", 52 | " return (self.src.getName()+\"->\"+self.dest.getName())" 53 | ] 54 | }, 55 | { 56 | "cell_type": "markdown", 57 | "metadata": {}, 58 | "source": [ 59 | "### Class Digraph" 60 | ] 61 | }, 62 | { 63 | "cell_type": "code", 64 | "execution_count": 3, 65 | "metadata": {}, 66 | "outputs": [], 67 | "source": [ 68 | "class Digraph(object):\n", 69 | " def __init__(self):\n", 70 | " self.edges={}\n", 71 | " \n", 72 | " def addNode(self,node):\n", 73 | " if node in self.edges:\n", 74 | " raise ValueError(\"Duplicate node\")\n", 75 | " else:\n", 76 | " self.edges[node]=[]\n", 77 | " print(f\"{node.getName()} added to the graph\")\n", 78 | " \n", 79 | " def addEdge(self,edge):\n", 80 | " src=edge.getSource()\n", 81 | " print(src)\n", 82 | " dest=edge.getDest()\n", 83 | " print(dest)\n", 84 | " if not (src in self.edges and dest in self.edges):\n", 85 | " raise ValueError(\"Node not in graph\")\n", 86 | " else:\n", 87 | " self.edges[src].append(dest) # Builds adjacency list\n", 88 | " \n", 89 | " def childrenOf(self,node):\n", 90 | " return self.edges[node]\n", 91 | " \n", 92 | " def hasNode(self,node):\n", 93 | " return node in self.edges\n", 94 | " \n", 95 | " def getNode(self,name):\n", 96 | " for n in self.edges:\n", 97 | " if n.getName()==name:\n", 98 | " return n\n", 99 | " raise NameError(name)\n", 100 | " \n", 101 | " def __str__(self):\n", 102 | " toPrint=''\n", 103 | " for src in self.edges:\n", 104 | " for dest in self.edges[src]:\n", 105 | " toPrint=toPrint+src.getName()+\"->\"+dest.getName()+\"\\n\"\n", 106 | " \n", 107 | " if (toPrint==''):\n", 108 | " return (\"Empty graph! Nothing to print\")\n", 109 | " else:\n", 110 | " return toPrint[:-1]" 111 | ] 112 | }, 113 | { 114 | "cell_type": "code", 115 | "execution_count": 4, 116 | "metadata": {}, 117 | "outputs": [], 118 | "source": [ 119 | "cities=['Chicago','Boston','New York','Salt Lake City','SFO','Seattle']" 120 | ] 121 | }, 122 | { 123 | "cell_type": "code", 124 | "execution_count": 5, 125 | "metadata": {}, 126 | "outputs": [], 127 | "source": [ 128 | "g=Digraph()" 129 | ] 130 | }, 131 | { 132 | "cell_type": "code", 133 | "execution_count": 6, 134 | "metadata": {}, 135 | "outputs": [], 136 | "source": [ 137 | "nodes=[]\n", 138 | "for c in cities:\n", 139 | " nodes.append(Node(c))" 140 | ] 141 | }, 142 | { 143 | "cell_type": "code", 144 | "execution_count": 7, 145 | "metadata": {}, 146 | "outputs": [ 147 | { 148 | "data": { 149 | "text/plain": [ 150 | "{}" 151 | ] 152 | }, 153 | "execution_count": 7, 154 | "metadata": {}, 155 | "output_type": "execute_result" 156 | } 157 | ], 158 | "source": [ 159 | "g.edges" 160 | ] 161 | }, 162 | { 163 | "cell_type": "code", 164 | "execution_count": 8, 165 | "metadata": {}, 166 | "outputs": [ 167 | { 168 | "name": "stdout", 169 | "output_type": "stream", 170 | "text": [ 171 | "Chicago added to the graph\n", 172 | "Boston added to the graph\n", 173 | "New York added to the graph\n", 174 | "Salt Lake City added to the graph\n", 175 | "SFO added to the graph\n", 176 | "Seattle added to the graph\n" 177 | ] 178 | } 179 | ], 180 | "source": [ 181 | "for n in nodes:\n", 182 | " g.addNode(n)" 183 | ] 184 | }, 185 | { 186 | "cell_type": "code", 187 | "execution_count": 9, 188 | "metadata": {}, 189 | "outputs": [ 190 | { 191 | "data": { 192 | "text/plain": [ 193 | "{<__main__.Node at 0x1f5464b3cf8>: [],\n", 194 | " <__main__.Node at 0x1f5464b3a58>: [],\n", 195 | " <__main__.Node at 0x1f5464b3a90>: [],\n", 196 | " <__main__.Node at 0x1f5464b3c88>: [],\n", 197 | " <__main__.Node at 0x1f5464b3c50>: [],\n", 198 | " <__main__.Node at 0x1f5464b3cc0>: []}" 199 | ] 200 | }, 201 | "execution_count": 9, 202 | "metadata": {}, 203 | "output_type": "execute_result" 204 | } 205 | ], 206 | "source": [ 207 | "g.edges" 208 | ] 209 | }, 210 | { 211 | "cell_type": "code", 212 | "execution_count": 10, 213 | "metadata": {}, 214 | "outputs": [ 215 | { 216 | "name": "stdout", 217 | "output_type": "stream", 218 | "text": [ 219 | "Chicago\n", 220 | "Boston\n", 221 | "New York\n", 222 | "Salt Lake City\n", 223 | "SFO\n", 224 | "Seattle\n" 225 | ] 226 | } 227 | ], 228 | "source": [ 229 | "for k in g.edges:\n", 230 | " print(k)" 231 | ] 232 | }, 233 | { 234 | "cell_type": "code", 235 | "execution_count": 11, 236 | "metadata": {}, 237 | "outputs": [ 238 | { 239 | "data": { 240 | "text/plain": [ 241 | "<__main__.Node at 0x1f5464b3cf8>" 242 | ] 243 | }, 244 | "execution_count": 11, 245 | "metadata": {}, 246 | "output_type": "execute_result" 247 | } 248 | ], 249 | "source": [ 250 | "nodes[1]" 251 | ] 252 | }, 253 | { 254 | "cell_type": "code", 255 | "execution_count": 12, 256 | "metadata": {}, 257 | "outputs": [], 258 | "source": [ 259 | "edge_chicago_boston=Edge(nodes[0],nodes[1])" 260 | ] 261 | }, 262 | { 263 | "cell_type": "code", 264 | "execution_count": 13, 265 | "metadata": {}, 266 | "outputs": [ 267 | { 268 | "data": { 269 | "text/plain": [ 270 | "<__main__.Node at 0x1f5464b3a58>" 271 | ] 272 | }, 273 | "execution_count": 13, 274 | "metadata": {}, 275 | "output_type": "execute_result" 276 | } 277 | ], 278 | "source": [ 279 | "edge_chicago_boston.getSource()" 280 | ] 281 | }, 282 | { 283 | "cell_type": "code", 284 | "execution_count": 14, 285 | "metadata": {}, 286 | "outputs": [ 287 | { 288 | "data": { 289 | "text/plain": [ 290 | "True" 291 | ] 292 | }, 293 | "execution_count": 14, 294 | "metadata": {}, 295 | "output_type": "execute_result" 296 | } 297 | ], 298 | "source": [ 299 | "g.hasNode(nodes[2])" 300 | ] 301 | }, 302 | { 303 | "cell_type": "code", 304 | "execution_count": 15, 305 | "metadata": {}, 306 | "outputs": [ 307 | { 308 | "data": { 309 | "text/plain": [ 310 | "<__main__.Node at 0x1f5464b3c88>" 311 | ] 312 | }, 313 | "execution_count": 15, 314 | "metadata": {}, 315 | "output_type": "execute_result" 316 | } 317 | ], 318 | "source": [ 319 | "g.getNode('SFO')" 320 | ] 321 | }, 322 | { 323 | "cell_type": "code", 324 | "execution_count": 16, 325 | "metadata": {}, 326 | "outputs": [], 327 | "source": [ 328 | "from graphviz import Graph\n", 329 | "dot=Graph(\"Roundtable\")" 330 | ] 331 | }, 332 | { 333 | "cell_type": "code", 334 | "execution_count": 17, 335 | "metadata": {}, 336 | "outputs": [], 337 | "source": [ 338 | "dot.node('A', 'King Arthur')\n", 339 | "dot.node('B', 'Sir Bedevere the Wise')\n", 340 | "dot.node('L', 'Sir Lancelot the Brave')" 341 | ] 342 | }, 343 | { 344 | "cell_type": "code", 345 | "execution_count": 18, 346 | "metadata": {}, 347 | "outputs": [], 348 | "source": [ 349 | "dot.edges(['AB', 'AL'])" 350 | ] 351 | }, 352 | { 353 | "cell_type": "code", 354 | "execution_count": 19, 355 | "metadata": {}, 356 | "outputs": [ 357 | { 358 | "name": "stdout", 359 | "output_type": "stream", 360 | "text": [ 361 | "graph Roundtable {\n", 362 | "\tA [label=\"King Arthur\"]\n", 363 | "\tB [label=\"Sir Bedevere the Wise\"]\n", 364 | "\tL [label=\"Sir Lancelot the Brave\"]\n", 365 | "\tA -- B\n", 366 | "\tA -- L\n", 367 | "}\n" 368 | ] 369 | } 370 | ], 371 | "source": [ 372 | " print(dot.source)" 373 | ] 374 | }, 375 | { 376 | "cell_type": "code", 377 | "execution_count": 26, 378 | "metadata": {}, 379 | "outputs": [], 380 | "source": [ 381 | "import os\n", 382 | "os.environ[\"PATH\"] += os.pathsep + \"C:\\\\Program Files (x86)\\\\Graphviz2.38\\\\bin\\\\\"" 383 | ] 384 | }, 385 | { 386 | "cell_type": "code", 387 | "execution_count": 29, 388 | "metadata": {}, 389 | "outputs": [ 390 | { 391 | "data": { 392 | "text/plain": [ 393 | "'test-output/round-table.gv.pdf'" 394 | ] 395 | }, 396 | "execution_count": 29, 397 | "metadata": {}, 398 | "output_type": "execute_result" 399 | } 400 | ], 401 | "source": [ 402 | "dot.render(view=True,cleanup=True)" 403 | ] 404 | }, 405 | { 406 | "cell_type": "code", 407 | "execution_count": 30, 408 | "metadata": {}, 409 | "outputs": [ 410 | { 411 | "data": { 412 | "text/plain": [ 413 | "'test-output/round-table.gv.pdf'" 414 | ] 415 | }, 416 | "execution_count": 30, 417 | "metadata": {}, 418 | "output_type": "execute_result" 419 | } 420 | ], 421 | "source": [ 422 | "dot.view()" 423 | ] 424 | }, 425 | { 426 | "cell_type": "code", 427 | "execution_count": 31, 428 | "metadata": {}, 429 | "outputs": [ 430 | { 431 | "data": { 432 | "image/svg+xml": [ 433 | "\r\n", 434 | "\r\n", 436 | "\r\n", 438 | "\r\n", 439 | "\r\n", 441 | "\r\n", 442 | "Roundtable\r\n", 443 | "\r\n", 444 | "\r\n", 445 | "A\r\n", 446 | "\r\n", 447 | "King Arthur\r\n", 448 | "\r\n", 449 | "\r\n", 450 | "B\r\n", 451 | "\r\n", 452 | "Sir Bedevere the Wise\r\n", 453 | "\r\n", 454 | "\r\n", 455 | "A--B\r\n", 456 | "\r\n", 457 | "\r\n", 458 | "\r\n", 459 | "L\r\n", 460 | "\r\n", 461 | "Sir Lancelot the Brave\r\n", 462 | "\r\n", 463 | "\r\n", 464 | "A--L\r\n", 465 | "\r\n", 466 | "\r\n", 467 | "\r\n", 468 | "\r\n" 469 | ], 470 | "text/plain": [ 471 | "" 472 | ] 473 | }, 474 | "execution_count": 31, 475 | "metadata": {}, 476 | "output_type": "execute_result" 477 | } 478 | ], 479 | "source": [ 480 | "dot" 481 | ] 482 | }, 483 | { 484 | "cell_type": "code", 485 | "execution_count": 33, 486 | "metadata": {}, 487 | "outputs": [ 488 | { 489 | "name": "stdout", 490 | "output_type": "stream", 491 | "text": [ 492 | "test-output/round-table.gv.pdf\n" 493 | ] 494 | } 495 | ], 496 | "source": [ 497 | "print(dot.view())" 498 | ] 499 | }, 500 | { 501 | "cell_type": "code", 502 | "execution_count": null, 503 | "metadata": {}, 504 | "outputs": [], 505 | "source": [] 506 | } 507 | ], 508 | "metadata": { 509 | "kernelspec": { 510 | "display_name": "Python 3", 511 | "language": "python", 512 | "name": "python3" 513 | }, 514 | "language_info": { 515 | "codemirror_mode": { 516 | "name": "ipython", 517 | "version": 3 518 | }, 519 | "file_extension": ".py", 520 | "mimetype": "text/x-python", 521 | "name": "python", 522 | "nbconvert_exporter": "python", 523 | "pygments_lexer": "ipython3", 524 | "version": "3.6.2" 525 | }, 526 | "latex_envs": { 527 | "LaTeX_envs_menu_present": true, 528 | "autoclose": false, 529 | "autocomplete": true, 530 | "bibliofile": "biblio.bib", 531 | "cite_by": "apalike", 532 | "current_citInitial": 1, 533 | "eqLabelWithNumbers": true, 534 | "eqNumInitial": 1, 535 | "hotkeys": { 536 | "equation": "Ctrl-E", 537 | "itemize": "Ctrl-I" 538 | }, 539 | "labels_anchors": false, 540 | "latex_user_defs": false, 541 | "report_style_numbering": false, 542 | "user_envs_cfg": false 543 | } 544 | }, 545 | "nbformat": 4, 546 | "nbformat_minor": 2 547 | } 548 | -------------------------------------------------------------------------------- /Data Structures/LinkedList-test.py: -------------------------------------------------------------------------------- 1 | from LinkedList import LinkedList, Node 2 | 3 | def main(): 4 | print() 5 | print("An empty list initialized...") 6 | ll = LinkedList() 7 | print("Is the list empty? ",ll.isEmpty()) 8 | print("Now a list with an initial value...") 9 | ll = LinkedList(Node(10)) 10 | ll.show() 11 | print("Is the list empty? ",ll.isEmpty()) 12 | print("Appending at the end...") 13 | ll.append(Node(20)) 14 | ll.show() 15 | print("Inserting at the beginning...") 16 | ll.insert_first(Node(100)) 17 | ll.show() 18 | print("Deleting the tail...") 19 | ll.delete_tail() 20 | ll.show() 21 | print("Inserting few more nodes...") 22 | ll.append(Node(25)) 23 | ll.append(Node(50)) 24 | ll.show() 25 | print("Length of the list:", ll.length()) 26 | print() 27 | 28 | if __name__ == "__main__": 29 | main() -------------------------------------------------------------------------------- /Data Structures/LinkedList.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Linked List in Python" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": {}, 14 | "outputs": [], 15 | "source": [ 16 | "class Node(object):\n", 17 | " def __init__(self, value):\n", 18 | " self.value = value\n", 19 | " self.next = None" 20 | ] 21 | }, 22 | { 23 | "cell_type": "code", 24 | "execution_count": 2, 25 | "metadata": {}, 26 | "outputs": [], 27 | "source": [ 28 | "n1 = Node(4)" 29 | ] 30 | }, 31 | { 32 | "cell_type": "code", 33 | "execution_count": 3, 34 | "metadata": {}, 35 | "outputs": [ 36 | { 37 | "data": { 38 | "text/plain": [ 39 | "4" 40 | ] 41 | }, 42 | "execution_count": 3, 43 | "metadata": {}, 44 | "output_type": "execute_result" 45 | } 46 | ], 47 | "source": [ 48 | "n1.value" 49 | ] 50 | }, 51 | { 52 | "cell_type": "code", 53 | "execution_count": 4, 54 | "metadata": {}, 55 | "outputs": [ 56 | { 57 | "name": "stdout", 58 | "output_type": "stream", 59 | "text": [ 60 | "None\n" 61 | ] 62 | } 63 | ], 64 | "source": [ 65 | "print(n1.next)" 66 | ] 67 | }, 68 | { 69 | "cell_type": "code", 70 | "execution_count": 5, 71 | "metadata": {}, 72 | "outputs": [], 73 | "source": [ 74 | "class LinkedList(object):\n", 75 | " def __init__(self, head=None):\n", 76 | " self.head = head" 77 | ] 78 | }, 79 | { 80 | "cell_type": "code", 81 | "execution_count": 6, 82 | "metadata": {}, 83 | "outputs": [], 84 | "source": [ 85 | "l1 = LinkedList()" 86 | ] 87 | }, 88 | { 89 | "cell_type": "code", 90 | "execution_count": 7, 91 | "metadata": {}, 92 | "outputs": [ 93 | { 94 | "name": "stdout", 95 | "output_type": "stream", 96 | "text": [ 97 | "None\n" 98 | ] 99 | } 100 | ], 101 | "source": [ 102 | "print(l1.head)" 103 | ] 104 | }, 105 | { 106 | "cell_type": "code", 107 | "execution_count": 8, 108 | "metadata": {}, 109 | "outputs": [], 110 | "source": [ 111 | "l2 = LinkedList(Node(5))" 112 | ] 113 | }, 114 | { 115 | "cell_type": "code", 116 | "execution_count": 9, 117 | "metadata": {}, 118 | "outputs": [ 119 | { 120 | "name": "stdout", 121 | "output_type": "stream", 122 | "text": [ 123 | "5\n" 124 | ] 125 | } 126 | ], 127 | "source": [ 128 | "print(l2.head.value)" 129 | ] 130 | }, 131 | { 132 | "cell_type": "markdown", 133 | "metadata": {}, 134 | "source": [ 135 | "## `Append` method\n", 136 | "If the `LinkedList` already has a `head`, iterate through the `next` reference in every `Node` until you reach the end of the list. Set `next` for the end of the list to be the `new_node`. Alternatively, if there is no `head` already, you should just assign `new_node` to it and do nothing else." 137 | ] 138 | }, 139 | { 140 | "cell_type": "code", 141 | "execution_count": 10, 142 | "metadata": {}, 143 | "outputs": [], 144 | "source": [ 145 | "class LinkedList(object):\n", 146 | " def __init__(self, head=None):\n", 147 | " self.head = head\n", 148 | " def append(self, new_node):\n", 149 | " current = self.head\n", 150 | " if self.head:\n", 151 | " while current.next:\n", 152 | " current = current.next\n", 153 | " current.next = new_node\n", 154 | " else:\n", 155 | " self.head = new_node" 156 | ] 157 | }, 158 | { 159 | "cell_type": "code", 160 | "execution_count": 11, 161 | "metadata": {}, 162 | "outputs": [], 163 | "source": [ 164 | "l3 = LinkedList(Node(10))" 165 | ] 166 | }, 167 | { 168 | "cell_type": "code", 169 | "execution_count": 12, 170 | "metadata": {}, 171 | "outputs": [ 172 | { 173 | "name": "stdout", 174 | "output_type": "stream", 175 | "text": [ 176 | "10\n" 177 | ] 178 | } 179 | ], 180 | "source": [ 181 | "print(l3.head.value)" 182 | ] 183 | }, 184 | { 185 | "cell_type": "code", 186 | "execution_count": 13, 187 | "metadata": {}, 188 | "outputs": [], 189 | "source": [ 190 | "n2 = Node(20)" 191 | ] 192 | }, 193 | { 194 | "cell_type": "code", 195 | "execution_count": 14, 196 | "metadata": {}, 197 | "outputs": [], 198 | "source": [ 199 | "l3.append(n2)" 200 | ] 201 | }, 202 | { 203 | "cell_type": "code", 204 | "execution_count": 15, 205 | "metadata": {}, 206 | "outputs": [ 207 | { 208 | "data": { 209 | "text/plain": [ 210 | "10" 211 | ] 212 | }, 213 | "execution_count": 15, 214 | "metadata": {}, 215 | "output_type": "execute_result" 216 | } 217 | ], 218 | "source": [ 219 | "l3.head.value" 220 | ] 221 | }, 222 | { 223 | "cell_type": "code", 224 | "execution_count": 16, 225 | "metadata": {}, 226 | "outputs": [ 227 | { 228 | "data": { 229 | "text/plain": [ 230 | "20" 231 | ] 232 | }, 233 | "execution_count": 16, 234 | "metadata": {}, 235 | "output_type": "execute_result" 236 | } 237 | ], 238 | "source": [ 239 | "l3.head.next.value" 240 | ] 241 | }, 242 | { 243 | "cell_type": "markdown", 244 | "metadata": {}, 245 | "source": [ 246 | "## `Show` method" 247 | ] 248 | }, 249 | { 250 | "cell_type": "code", 251 | "execution_count": 17, 252 | "metadata": {}, 253 | "outputs": [], 254 | "source": [ 255 | "class LinkedList(object):\n", 256 | " def __init__(self, head=None):\n", 257 | " self.head = head\n", 258 | " def append(self, new_node):\n", 259 | " \"\"\"\n", 260 | " Appends a new node at the end\n", 261 | " \"\"\"\n", 262 | " current = self.head\n", 263 | " if self.head:\n", 264 | " while current.next:\n", 265 | " current = current.next\n", 266 | " current.next = new_node\n", 267 | " else:\n", 268 | " self.head = new_node\n", 269 | " def show(self):\n", 270 | " \"\"\"\n", 271 | " Shows (prints) a linked list\n", 272 | " \"\"\"\n", 273 | " print('[',end='')\n", 274 | " current = self.head\n", 275 | " if self.head:\n", 276 | " if current.next:\n", 277 | " print(self.head.value,end=', ')\n", 278 | " else:\n", 279 | " print(self.head.value,end='')\n", 280 | " while current.next:\n", 281 | " current = current.next\n", 282 | " if current.next:\n", 283 | " print(current.value,end=', ')\n", 284 | " else:\n", 285 | " print(current.value,end='')\n", 286 | " print(']')" 287 | ] 288 | }, 289 | { 290 | "cell_type": "code", 291 | "execution_count": 18, 292 | "metadata": {}, 293 | "outputs": [], 294 | "source": [ 295 | "l3 = LinkedList(Node(10))" 296 | ] 297 | }, 298 | { 299 | "cell_type": "code", 300 | "execution_count": 19, 301 | "metadata": {}, 302 | "outputs": [ 303 | { 304 | "name": "stdout", 305 | "output_type": "stream", 306 | "text": [ 307 | "[10]\n" 308 | ] 309 | } 310 | ], 311 | "source": [ 312 | "l3.show()" 313 | ] 314 | }, 315 | { 316 | "cell_type": "code", 317 | "execution_count": 20, 318 | "metadata": {}, 319 | "outputs": [], 320 | "source": [ 321 | "l3.append(Node(20))" 322 | ] 323 | }, 324 | { 325 | "cell_type": "code", 326 | "execution_count": 21, 327 | "metadata": {}, 328 | "outputs": [ 329 | { 330 | "data": { 331 | "text/plain": [ 332 | "20" 333 | ] 334 | }, 335 | "execution_count": 21, 336 | "metadata": {}, 337 | "output_type": "execute_result" 338 | } 339 | ], 340 | "source": [ 341 | "l3.head.next.value" 342 | ] 343 | }, 344 | { 345 | "cell_type": "code", 346 | "execution_count": 22, 347 | "metadata": {}, 348 | "outputs": [ 349 | { 350 | "name": "stdout", 351 | "output_type": "stream", 352 | "text": [ 353 | "[10, 20]\n" 354 | ] 355 | } 356 | ], 357 | "source": [ 358 | "l3.show()" 359 | ] 360 | }, 361 | { 362 | "cell_type": "code", 363 | "execution_count": 23, 364 | "metadata": {}, 365 | "outputs": [], 366 | "source": [ 367 | "l3 = LinkedList(Node(10))\n", 368 | "l3.append(Node(20))\n", 369 | "l3.append(Node(30))" 370 | ] 371 | }, 372 | { 373 | "cell_type": "code", 374 | "execution_count": 24, 375 | "metadata": {}, 376 | "outputs": [ 377 | { 378 | "name": "stdout", 379 | "output_type": "stream", 380 | "text": [ 381 | "[10, 20, 30]\n" 382 | ] 383 | } 384 | ], 385 | "source": [ 386 | "l3.show()" 387 | ] 388 | }, 389 | { 390 | "cell_type": "markdown", 391 | "metadata": {}, 392 | "source": [ 393 | "## Two more methods - `insert_first` and `delete_first`\n", 394 | "These methods will be useful to build a `Stack` class later." 395 | ] 396 | }, 397 | { 398 | "cell_type": "code", 399 | "execution_count": 25, 400 | "metadata": {}, 401 | "outputs": [], 402 | "source": [ 403 | "class LinkedList(object):\n", 404 | " \n", 405 | " def __init__(self, head=None):\n", 406 | " self.head = head\n", 407 | " \n", 408 | " def append(self, new_node):\n", 409 | " \"\"\"\n", 410 | " Appends a new node at the end\n", 411 | " \"\"\"\n", 412 | " current = self.head\n", 413 | " if self.head:\n", 414 | " while current.next:\n", 415 | " current = current.next\n", 416 | " current.next = new_node\n", 417 | " else:\n", 418 | " self.head = new_node\n", 419 | " \n", 420 | " def show(self):\n", 421 | " \"\"\"\n", 422 | " Shows (prints) a linked list\n", 423 | " \"\"\"\n", 424 | " print('[',end='')\n", 425 | " current = self.head\n", 426 | " if self.head:\n", 427 | " if current.next:\n", 428 | " print(self.head.value,end=', ')\n", 429 | " else:\n", 430 | " print(self.head.value,end='')\n", 431 | " while current.next:\n", 432 | " current = current.next\n", 433 | " if current.next:\n", 434 | " print(current.value,end=', ')\n", 435 | " else:\n", 436 | " print(current.value,end='')\n", 437 | " print(']')\n", 438 | " \n", 439 | " def insert_first(self, new_node):\n", 440 | " \"\"\"\n", 441 | " Inserts a new node at the beginning\n", 442 | " \"\"\"\n", 443 | " new_node.next = self.head\n", 444 | " self.head = new_node\n", 445 | "\n", 446 | " def delete_first(self):\n", 447 | " \"\"\"\n", 448 | " Deletes a node from the beginning\n", 449 | " \"\"\"\n", 450 | " if self.head:\n", 451 | " deleted_element = self.head\n", 452 | " temp = deleted_element.next\n", 453 | " self.head = temp\n", 454 | " return deleted_element\n", 455 | " else:\n", 456 | " return None" 457 | ] 458 | }, 459 | { 460 | "cell_type": "code", 461 | "execution_count": 26, 462 | "metadata": {}, 463 | "outputs": [], 464 | "source": [ 465 | "l4 = LinkedList(Node(10))" 466 | ] 467 | }, 468 | { 469 | "cell_type": "code", 470 | "execution_count": 27, 471 | "metadata": {}, 472 | "outputs": [ 473 | { 474 | "name": "stdout", 475 | "output_type": "stream", 476 | "text": [ 477 | "[10]\n" 478 | ] 479 | } 480 | ], 481 | "source": [ 482 | "l4.show()" 483 | ] 484 | }, 485 | { 486 | "cell_type": "code", 487 | "execution_count": 28, 488 | "metadata": {}, 489 | "outputs": [], 490 | "source": [ 491 | "l4.append(Node(20))\n", 492 | "l4.append(Node(30))" 493 | ] 494 | }, 495 | { 496 | "cell_type": "code", 497 | "execution_count": 29, 498 | "metadata": {}, 499 | "outputs": [ 500 | { 501 | "name": "stdout", 502 | "output_type": "stream", 503 | "text": [ 504 | "[10, 20, 30]\n" 505 | ] 506 | } 507 | ], 508 | "source": [ 509 | "l4.show()" 510 | ] 511 | }, 512 | { 513 | "cell_type": "code", 514 | "execution_count": 30, 515 | "metadata": {}, 516 | "outputs": [ 517 | { 518 | "data": { 519 | "text/plain": [ 520 | "<__main__.Node at 0x12ad02d4be0>" 521 | ] 522 | }, 523 | "execution_count": 30, 524 | "metadata": {}, 525 | "output_type": "execute_result" 526 | } 527 | ], 528 | "source": [ 529 | "l4.delete_first()" 530 | ] 531 | }, 532 | { 533 | "cell_type": "code", 534 | "execution_count": 31, 535 | "metadata": {}, 536 | "outputs": [ 537 | { 538 | "name": "stdout", 539 | "output_type": "stream", 540 | "text": [ 541 | "[20, 30]\n" 542 | ] 543 | } 544 | ], 545 | "source": [ 546 | "l4.show()" 547 | ] 548 | }, 549 | { 550 | "cell_type": "code", 551 | "execution_count": 32, 552 | "metadata": {}, 553 | "outputs": [], 554 | "source": [ 555 | "l4.insert_first(Node(5))" 556 | ] 557 | }, 558 | { 559 | "cell_type": "code", 560 | "execution_count": 33, 561 | "metadata": {}, 562 | "outputs": [ 563 | { 564 | "name": "stdout", 565 | "output_type": "stream", 566 | "text": [ 567 | "[5, 20, 30]\n" 568 | ] 569 | } 570 | ], 571 | "source": [ 572 | "l4.show()" 573 | ] 574 | }, 575 | { 576 | "cell_type": "markdown", 577 | "metadata": {}, 578 | "source": [ 579 | "## A few more - `delete_tail`, `length`, `is_Empty`" 580 | ] 581 | }, 582 | { 583 | "cell_type": "code", 584 | "execution_count": 34, 585 | "metadata": {}, 586 | "outputs": [], 587 | "source": [ 588 | "class LinkedList(object):\n", 589 | " \n", 590 | " def __init__(self, head=None):\n", 591 | " self.head = head\n", 592 | " \n", 593 | " def append(self, new_node):\n", 594 | " \"\"\"\n", 595 | " Appends a new node at the end\n", 596 | " \"\"\"\n", 597 | " current = self.head\n", 598 | " if self.head:\n", 599 | " while current.next:\n", 600 | " current = current.next\n", 601 | " current.next = new_node\n", 602 | " else:\n", 603 | " self.head = new_node\n", 604 | " \n", 605 | " def show(self):\n", 606 | " \"\"\"\n", 607 | " Shows (prints) a linked list\n", 608 | " \"\"\"\n", 609 | " print('[',end='')\n", 610 | " current = self.head\n", 611 | " if self.head:\n", 612 | " if current.next:\n", 613 | " print(self.head.value,end=', ')\n", 614 | " else:\n", 615 | " print(self.head.value,end='')\n", 616 | " while current.next:\n", 617 | " current = current.next\n", 618 | " if current.next:\n", 619 | " print(current.value,end=', ')\n", 620 | " else:\n", 621 | " print(current.value,end='')\n", 622 | " print(']')\n", 623 | " \n", 624 | " def insert_first(self, new_node):\n", 625 | " \"\"\"\n", 626 | " Inserts a new node at the beginning\n", 627 | " \"\"\"\n", 628 | " new_node.next = self.head\n", 629 | " self.head = new_node\n", 630 | "\n", 631 | " def delete_first(self):\n", 632 | " \"\"\"\n", 633 | " Deletes a node from the beginning\n", 634 | " \"\"\"\n", 635 | " if self.head:\n", 636 | " deleted_element = self.head\n", 637 | " temp = deleted_element.next\n", 638 | " self.head = temp\n", 639 | " return deleted_element\n", 640 | " else:\n", 641 | " return None\n", 642 | " \n", 643 | " def delete_tail(self):\n", 644 | " temp = self.head\n", 645 | " if self.head != None:\n", 646 | " if self.head.next is None: # if Head is the only Node in the Linked List\n", 647 | " self.head = None\n", 648 | " else:\n", 649 | " while temp.next.next is not None: # find the 2nd last element\n", 650 | " temp = temp.next\n", 651 | " temp.next, temp = (\n", 652 | " None,\n", 653 | " temp.next,\n", 654 | " ) # (2nd last element).next = None and temp = last element\n", 655 | " return temp\n", 656 | " \n", 657 | " def isEmpty(self):\n", 658 | " \"\"\"\n", 659 | " Returns a Boolean whether the list is empty\n", 660 | " \"\"\"\n", 661 | " return self.head is None # Return if Head is none\n", 662 | " \n", 663 | " def length(self):\n", 664 | " \"\"\"\n", 665 | " Returns the length of the list\n", 666 | " \"\"\"\n", 667 | " ln = 0\n", 668 | " if not self.isEmpty():\n", 669 | " ln+=1\n", 670 | " current = self.head\n", 671 | " if self.head:\n", 672 | " while current.next:\n", 673 | " current = current.next\n", 674 | " ln+=1\n", 675 | " return ln" 676 | ] 677 | }, 678 | { 679 | "cell_type": "code", 680 | "execution_count": 35, 681 | "metadata": {}, 682 | "outputs": [], 683 | "source": [ 684 | "l5 = LinkedList(Node(10))\n", 685 | "l5.append(Node(20))\n", 686 | "l5.append(Node(30))" 687 | ] 688 | }, 689 | { 690 | "cell_type": "code", 691 | "execution_count": 36, 692 | "metadata": {}, 693 | "outputs": [ 694 | { 695 | "name": "stdout", 696 | "output_type": "stream", 697 | "text": [ 698 | "[10, 20, 30]\n" 699 | ] 700 | } 701 | ], 702 | "source": [ 703 | "l5.show()" 704 | ] 705 | }, 706 | { 707 | "cell_type": "code", 708 | "execution_count": 37, 709 | "metadata": {}, 710 | "outputs": [ 711 | { 712 | "data": { 713 | "text/plain": [ 714 | "3" 715 | ] 716 | }, 717 | "execution_count": 37, 718 | "metadata": {}, 719 | "output_type": "execute_result" 720 | } 721 | ], 722 | "source": [ 723 | "l5.length()" 724 | ] 725 | }, 726 | { 727 | "cell_type": "code", 728 | "execution_count": 38, 729 | "metadata": {}, 730 | "outputs": [ 731 | { 732 | "data": { 733 | "text/plain": [ 734 | "<__main__.Node at 0x12ad02d97f0>" 735 | ] 736 | }, 737 | "execution_count": 38, 738 | "metadata": {}, 739 | "output_type": "execute_result" 740 | } 741 | ], 742 | "source": [ 743 | "l5.delete_tail()" 744 | ] 745 | }, 746 | { 747 | "cell_type": "code", 748 | "execution_count": 39, 749 | "metadata": {}, 750 | "outputs": [ 751 | { 752 | "name": "stdout", 753 | "output_type": "stream", 754 | "text": [ 755 | "[10, 20]\n" 756 | ] 757 | } 758 | ], 759 | "source": [ 760 | "l5.show()" 761 | ] 762 | }, 763 | { 764 | "cell_type": "code", 765 | "execution_count": 40, 766 | "metadata": {}, 767 | "outputs": [ 768 | { 769 | "data": { 770 | "text/plain": [ 771 | "2" 772 | ] 773 | }, 774 | "execution_count": 40, 775 | "metadata": {}, 776 | "output_type": "execute_result" 777 | } 778 | ], 779 | "source": [ 780 | "l5.length()" 781 | ] 782 | }, 783 | { 784 | "cell_type": "code", 785 | "execution_count": 41, 786 | "metadata": {}, 787 | "outputs": [ 788 | { 789 | "data": { 790 | "text/plain": [ 791 | "<__main__.Node at 0x12ad02d9630>" 792 | ] 793 | }, 794 | "execution_count": 41, 795 | "metadata": {}, 796 | "output_type": "execute_result" 797 | } 798 | ], 799 | "source": [ 800 | "l5.delete_tail()\n", 801 | "l5.delete_first()" 802 | ] 803 | }, 804 | { 805 | "cell_type": "code", 806 | "execution_count": 42, 807 | "metadata": {}, 808 | "outputs": [ 809 | { 810 | "data": { 811 | "text/plain": [ 812 | "True" 813 | ] 814 | }, 815 | "execution_count": 42, 816 | "metadata": {}, 817 | "output_type": "execute_result" 818 | } 819 | ], 820 | "source": [ 821 | "l5.isEmpty()" 822 | ] 823 | } 824 | ], 825 | "metadata": { 826 | "kernelspec": { 827 | "display_name": "Python 3", 828 | "language": "python", 829 | "name": "python3" 830 | }, 831 | "language_info": { 832 | "codemirror_mode": { 833 | "name": "ipython", 834 | "version": 3 835 | }, 836 | "file_extension": ".py", 837 | "mimetype": "text/x-python", 838 | "name": "python", 839 | "nbconvert_exporter": "python", 840 | "pygments_lexer": "ipython3", 841 | "version": "3.7.0" 842 | } 843 | }, 844 | "nbformat": 4, 845 | "nbformat_minor": 4 846 | } 847 | -------------------------------------------------------------------------------- /Data Structures/LinkedList.py: -------------------------------------------------------------------------------- 1 | class Node(object): 2 | """ 3 | The basic node class storing a value and a 'next' pointer to the next node 4 | """ 5 | def __init__(self, value): 6 | self.value = value 7 | self.next = None 8 | 9 | class LinkedList(object): 10 | """ 11 | The linked list class 12 | """ 13 | def __init__(self, head=None): 14 | self.head = head 15 | 16 | def append(self, new_node): 17 | """ 18 | Appends a new node at the end 19 | """ 20 | current = self.head 21 | if self.head: 22 | while current.next: 23 | current = current.next 24 | current.next = new_node 25 | else: 26 | self.head = new_node 27 | 28 | def show(self): 29 | """ 30 | Shows (prints) a linked list 31 | """ 32 | print('[',end='') 33 | current = self.head 34 | if self.head: 35 | if current.next: 36 | print(self.head.value,end=', ') 37 | else: 38 | print(self.head.value,end='') 39 | while current.next: 40 | current = current.next 41 | if current.next: 42 | print(current.value,end=', ') 43 | else: 44 | print(current.value,end='') 45 | print(']') 46 | 47 | def insert_first(self, new_node): 48 | """ 49 | Inserts a new node at the beginning 50 | """ 51 | new_node.next = self.head 52 | self.head = new_node 53 | 54 | def delete_first(self): 55 | """ 56 | Deletes a node from the beginning 57 | """ 58 | if self.head: 59 | deleted_element = self.head 60 | temp = deleted_element.next 61 | self.head = temp 62 | return deleted_element 63 | else: 64 | return None 65 | 66 | def delete_tail(self): 67 | """ 68 | Deletes a node from the end of the list 69 | """ 70 | temp = self.head 71 | if self.head != None: 72 | if self.head.next is None: # if Head is the only Node in the Linked List 73 | self.head = None 74 | else: 75 | while temp.next.next is not None: # find the 2nd last element 76 | temp = temp.next 77 | temp.next, temp = ( 78 | None, 79 | temp.next, 80 | ) # (2nd last element).next = None and temp = last element 81 | return temp 82 | 83 | def isEmpty(self): 84 | """ 85 | Returns a Boolean after checking whether the list is empty 86 | """ 87 | return self.head is None # Return if Head is none 88 | 89 | def length(self): 90 | """ 91 | Returns the length of the list 92 | """ 93 | ln = 0 94 | if not self.isEmpty(): 95 | ln+=1 96 | current = self.head 97 | if self.head: 98 | while current.next: 99 | current = current.next 100 | ln+=1 101 | return ln -------------------------------------------------------------------------------- /Data Structures/Misc Data Structures.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Stack" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | <<<<<<< HEAD 13 | "execution_count": null, 14 | ======= 15 | "execution_count": 1, 16 | >>>>>>> 8fd55a64ed3aa6820e41d3d04064e62a93184ac4 17 | "metadata": {}, 18 | "outputs": [], 19 | "source": [ 20 | "class Stack:\n", 21 | " \"\"\"\n", 22 | " Stack data structure using list\n", 23 | " \"\"\"\n", 24 | " def __init__(self,value=None,name=None,verbose=False):\n", 25 | " \"\"\"\n", 26 | " Class initializer: Produces a stack with a single value or a list of values\n", 27 | " value: The initial value. Could be a list of a single item.\n", 28 | " name: Optional name for the stack.\n", 29 | " verbose: Boolean. Determines if each stack operation prints the item being pushed or popped.\n", 30 | " \"\"\"\n", 31 | " self._items = []\n", 32 | " self._height=0\n", 33 | " self._verbose=verbose\n", 34 | " \n", 35 | " if value!=None: \n", 36 | " if type(value)==list:\n", 37 | " for v in value:\n", 38 | " self._items.append(v)\n", 39 | " self._height = len(value)\n", 40 | " else:\n", 41 | " self._items.append(value)\n", 42 | " self._height = 1\n", 43 | " else:\n", 44 | " print(\"Empty stack created.\")\n", 45 | " \n", 46 | " if name!=None:\n", 47 | " self._name=str(name)\n", 48 | " else:\n", 49 | " self._name=''\n", 50 | " \n", 51 | " def pop(self):\n", 52 | " if self._height == 0:\n", 53 | " print (\"Stack is empty. Nothing to pop.\")\n", 54 | " return None\n", 55 | " else:\n", 56 | " self._height -=1\n", 57 | " item=self._items.pop()\n", 58 | " if self._verbose:\n", 59 | " print(\"{} popped\".format(item))\n", 60 | " return item\n", 61 | " \n", 62 | " def push(self,value=None):\n", 63 | " \"\"\"\n", 64 | " Pushes a a single value or a list of values onto the stack\n", 65 | " \"\"\"\n", 66 | " if value!=None: \n", 67 | " if type(value)==list:\n", 68 | " for v in value:\n", 69 | " self._items.append(v)\n", 70 | " if self._verbose:\n", 71 | " print(\"{} pushed\".format(v))\n", 72 | " self._height += len(value)\n", 73 | " else:\n", 74 | " self._height +=1\n", 75 | " self._items.append(value)\n", 76 | " if self._verbose:\n", 77 | " print(\"{} pushed\".format(value))\n", 78 | " else:\n", 79 | " if self._verbose:\n", 80 | " print(\"No value supplied, nothing was pushed.\")\n", 81 | " \n", 82 | " def isEmpty(self):\n", 83 | " \"\"\"\n", 84 | " Returns (Boolean) if the stack is empty\n", 85 | " \"\"\"\n", 86 | " return self._height==0\n", 87 | " \n", 88 | " def draw(self):\n", 89 | " \"\"\"\n", 90 | " Prints the stack structure as a vertical representation \n", 91 | " \"\"\"\n", 92 | " if self.isEmpty():\n", 93 | " pass\n", 94 | " return None\n", 95 | " else:\n", 96 | " print(\"=\"*15)\n", 97 | " n=self._height\n", 98 | " print('['+str(self._items[n-1])+']')\n", 99 | " for i in range(n-2,-1,-1):\n", 100 | " print(\" | \")\n", 101 | " print('['+str(self._items[i])+']')\n", 102 | " print(\"=\"*15)\n", 103 | " \n", 104 | " def height(self):\n", 105 | " \"\"\"\n", 106 | " Returns stack height\n", 107 | " \"\"\"\n", 108 | " return (self._height)\n", 109 | " \n", 110 | " def __str__(self):\n", 111 | " \"\"\"\n", 112 | " Returns stack name to print method\n", 113 | " \"\"\"\n", 114 | " return (self._name)\n", 115 | " \n", 116 | " def set_verbosity(self,boolean):\n", 117 | " \"\"\"\n", 118 | " Sets the verbosity of the stack operation\n", 119 | " \"\"\"\n", 120 | " self._verbose=boolean" 121 | ] 122 | }, 123 | { 124 | "cell_type": "code", 125 | <<<<<<< HEAD 126 | "execution_count": null, 127 | "metadata": {}, 128 | "outputs": [], 129 | ======= 130 | "execution_count": 2, 131 | "metadata": {}, 132 | "outputs": [ 133 | { 134 | "name": "stdout", 135 | "output_type": "stream", 136 | "text": [ 137 | "===============\n", 138 | "[10]\n", 139 | " | \n", 140 | "[8]\n", 141 | " | \n", 142 | "[6]\n", 143 | " | \n", 144 | "[4]\n", 145 | " | \n", 146 | "[2]\n", 147 | " | \n", 148 | "[start]\n", 149 | "===============\n" 150 | ] 151 | } 152 | ], 153 | >>>>>>> 8fd55a64ed3aa6820e41d3d04064e62a93184ac4 154 | "source": [ 155 | "s=Stack('start',name='TestStack')\n", 156 | "for i in range(2,12,2):\n", 157 | " s.push(i)\n", 158 | "s.draw()" 159 | ] 160 | }, 161 | { 162 | "cell_type": "code", 163 | <<<<<<< HEAD 164 | "execution_count": null, 165 | "metadata": {}, 166 | "outputs": [], 167 | ======= 168 | "execution_count": 3, 169 | "metadata": {}, 170 | "outputs": [ 171 | { 172 | "name": "stdout", 173 | "output_type": "stream", 174 | "text": [ 175 | "===============\n", 176 | "[6]\n", 177 | " | \n", 178 | "[4]\n", 179 | " | \n", 180 | "[2]\n", 181 | " | \n", 182 | "[start]\n", 183 | "===============\n" 184 | ] 185 | } 186 | ], 187 | >>>>>>> 8fd55a64ed3aa6820e41d3d04064e62a93184ac4 188 | "source": [ 189 | "s.pop()\n", 190 | "s.pop()\n", 191 | "s.draw()" 192 | ] 193 | }, 194 | { 195 | "cell_type": "code", 196 | <<<<<<< HEAD 197 | "execution_count": null, 198 | "metadata": { 199 | "scrolled": false 200 | }, 201 | "outputs": [], 202 | ======= 203 | "execution_count": 4, 204 | "metadata": { 205 | "scrolled": false 206 | }, 207 | "outputs": [ 208 | { 209 | "name": "stdout", 210 | "output_type": "stream", 211 | "text": [ 212 | "===============\n", 213 | "[start]\n", 214 | "===============\n", 215 | "===============\n", 216 | "[2]\n", 217 | " | \n", 218 | "[start]\n", 219 | "===============\n", 220 | "===============\n", 221 | "[4]\n", 222 | " | \n", 223 | "[2]\n", 224 | " | \n", 225 | "[start]\n", 226 | "===============\n", 227 | "===============\n", 228 | "[6]\n", 229 | " | \n", 230 | "[4]\n", 231 | " | \n", 232 | "[2]\n", 233 | " | \n", 234 | "[start]\n", 235 | "===============\n", 236 | "===============\n", 237 | "[8]\n", 238 | " | \n", 239 | "[6]\n", 240 | " | \n", 241 | "[4]\n", 242 | " | \n", 243 | "[2]\n", 244 | " | \n", 245 | "[start]\n", 246 | "===============\n", 247 | "===============\n", 248 | "[10]\n", 249 | " | \n", 250 | "[8]\n", 251 | " | \n", 252 | "[6]\n", 253 | " | \n", 254 | "[4]\n", 255 | " | \n", 256 | "[2]\n", 257 | " | \n", 258 | "[start]\n", 259 | "===============\n", 260 | "===============\n", 261 | "[8]\n", 262 | " | \n", 263 | "[6]\n", 264 | " | \n", 265 | "[4]\n", 266 | " | \n", 267 | "[2]\n", 268 | " | \n", 269 | "[start]\n", 270 | "===============\n", 271 | "===============\n", 272 | "[6]\n", 273 | " | \n", 274 | "[4]\n", 275 | " | \n", 276 | "[2]\n", 277 | " | \n", 278 | "[start]\n", 279 | "===============\n", 280 | "===============\n", 281 | "[4]\n", 282 | " | \n", 283 | "[2]\n", 284 | " | \n", 285 | "[start]\n", 286 | "===============\n", 287 | "===============\n", 288 | "[100]\n", 289 | " | \n", 290 | "[4]\n", 291 | " | \n", 292 | "[2]\n", 293 | " | \n", 294 | "[start]\n", 295 | "===============\n", 296 | "===============\n", 297 | "[2]\n", 298 | " | \n", 299 | "[start]\n", 300 | "===============\n", 301 | "===============\n", 302 | "[7]\n", 303 | " | \n", 304 | "[5]\n", 305 | " | \n", 306 | "[3]\n", 307 | " | \n", 308 | "[2]\n", 309 | " | \n", 310 | "[start]\n", 311 | "===============\n", 312 | "===============\n", 313 | "[7]\n", 314 | " | \n", 315 | "[5]\n", 316 | " | \n", 317 | "[3]\n", 318 | " | \n", 319 | "[2]\n", 320 | " | \n", 321 | "[start]\n", 322 | "===============\n" 323 | ] 324 | } 325 | ], 326 | >>>>>>> 8fd55a64ed3aa6820e41d3d04064e62a93184ac4 327 | "source": [ 328 | "s=Stack('start',name='TestStack')\n", 329 | "s.draw()\n", 330 | "for i in range(2,12,2):\n", 331 | " s.push(i)\n", 332 | " s.draw()\n", 333 | "for i in range(3):\n", 334 | " s.pop()\n", 335 | " s.draw()\n", 336 | "s.push(100)\n", 337 | "s.draw()\n", 338 | "s.pop()\n", 339 | "s.pop()\n", 340 | "s.draw()\n", 341 | "s.push([3,5,7])\n", 342 | "s.draw()\n", 343 | "s.draw()" 344 | ] 345 | }, 346 | { 347 | "cell_type": "markdown", 348 | "metadata": {}, 349 | "source": [ 350 | "## Queue" 351 | ] 352 | }, 353 | { 354 | "cell_type": "code", 355 | <<<<<<< HEAD 356 | "execution_count": null, 357 | ======= 358 | "execution_count": 5, 359 | >>>>>>> 8fd55a64ed3aa6820e41d3d04064e62a93184ac4 360 | "metadata": {}, 361 | "outputs": [], 362 | "source": [ 363 | "class Queue:\n", 364 | " \"\"\"\n", 365 | " Queue data structure using list\n", 366 | " \"\"\"\n", 367 | " def __init__(self,value=None,name=None,verbose=False):\n", 368 | " \"\"\"\n", 369 | " Class initializer: Produces a queue with a single value or a list of values\n", 370 | " value: The initial value. Could be a list of a single item.\n", 371 | " name: Optional name for the queue.\n", 372 | " verbose: Boolean. Determines if each queue operation prints the item being pushed or popped.\n", 373 | " \"\"\"\n", 374 | " self._items = []\n", 375 | " self._length=0\n", 376 | " self._verbose=verbose\n", 377 | " \n", 378 | " if value!=None: \n", 379 | " if type(value)==list:\n", 380 | " for v in value:\n", 381 | " self._items.append(v)\n", 382 | " self._length = len(value)\n", 383 | " else:\n", 384 | " self._items.append(value)\n", 385 | " self._length = 1\n", 386 | " else:\n", 387 | " print(\"Empty queue created.\")\n", 388 | " \n", 389 | " if name!=None:\n", 390 | " self._name=str(name)\n", 391 | " else:\n", 392 | " self._name=''\n", 393 | " \n", 394 | " def dequeue(self):\n", 395 | " if self._length == 0:\n", 396 | " print (\"Queue is empty. Nothing to pop.\")\n", 397 | " return None\n", 398 | " else:\n", 399 | " self._length -=1\n", 400 | " item=self._items.pop(0)\n", 401 | " if self._verbose:\n", 402 | " print(\"{} dequeued\".format(item))\n", 403 | " return item\n", 404 | " \n", 405 | " def enqueue(self,value=None):\n", 406 | " \"\"\"\n", 407 | " Pushes a a single value or a list of values onto the queue\n", 408 | " \"\"\"\n", 409 | " if value!=None: \n", 410 | " if type(value)==list:\n", 411 | " for v in value:\n", 412 | " self._items.append(v)\n", 413 | " if self._verbose:\n", 414 | " print(\"{} enqueued\".format(v))\n", 415 | " self._length += len(value)\n", 416 | " else:\n", 417 | " self._length +=1\n", 418 | " self._items.append(value)\n", 419 | " if self._verbose:\n", 420 | " print(\"{} enqueued\".format(value))\n", 421 | " else:\n", 422 | " if self._verbose:\n", 423 | " print(\"No value supplied, nothing was enqueued.\")\n", 424 | " \n", 425 | " def isEmpty(self):\n", 426 | " \"\"\"\n", 427 | " Returns (Boolean) if the queue is empty\n", 428 | " \"\"\"\n", 429 | " return self._length==0\n", 430 | " \n", 431 | " def draw(self):\n", 432 | " if self.isEmpty():\n", 433 | " pass\n", 434 | " return None\n", 435 | " else:\n", 436 | " n=self._length\n", 437 | " for i in range(n-1):\n", 438 | " print('['+str(self._items[i])+']-',end='')\n", 439 | " print('['+str(self._items[n-1])+']')\n", 440 | " \n", 441 | " def length(self):\n", 442 | " \"\"\"\n", 443 | " Returns queue height\n", 444 | " \"\"\"\n", 445 | " return (self._length)\n", 446 | " \n", 447 | " def __str__(self):\n", 448 | " \"\"\"\n", 449 | " Returns queue name to print method\n", 450 | " \"\"\"\n", 451 | " return (self._name)\n", 452 | " \n", 453 | " def set_verbosity(self,boolean):\n", 454 | " \"\"\"\n", 455 | " Sets the verbosity of the queue operation\n", 456 | " \"\"\"\n", 457 | " self._verbose=boolean" 458 | ] 459 | }, 460 | { 461 | "cell_type": "code", 462 | <<<<<<< HEAD 463 | "execution_count": null, 464 | ======= 465 | "execution_count": 6, 466 | >>>>>>> 8fd55a64ed3aa6820e41d3d04064e62a93184ac4 467 | "metadata": {}, 468 | "outputs": [], 469 | "source": [ 470 | "q=Queue([2,3,6],verbose=True)" 471 | ] 472 | }, 473 | { 474 | "cell_type": "code", 475 | <<<<<<< HEAD 476 | "execution_count": null, 477 | "metadata": {}, 478 | "outputs": [], 479 | ======= 480 | "execution_count": 7, 481 | "metadata": {}, 482 | "outputs": [ 483 | { 484 | "data": { 485 | "text/plain": [ 486 | "<__main__.Queue at 0x165b0b74240>" 487 | ] 488 | }, 489 | "execution_count": 7, 490 | "metadata": {}, 491 | "output_type": "execute_result" 492 | } 493 | ], 494 | >>>>>>> 8fd55a64ed3aa6820e41d3d04064e62a93184ac4 495 | "source": [ 496 | "q" 497 | ] 498 | }, 499 | { 500 | "cell_type": "code", 501 | <<<<<<< HEAD 502 | "execution_count": null, 503 | "metadata": {}, 504 | "outputs": [], 505 | ======= 506 | "execution_count": 8, 507 | "metadata": {}, 508 | "outputs": [ 509 | { 510 | "name": "stdout", 511 | "output_type": "stream", 512 | "text": [ 513 | "[2]-[3]-[6]\n" 514 | ] 515 | } 516 | ], 517 | >>>>>>> 8fd55a64ed3aa6820e41d3d04064e62a93184ac4 518 | "source": [ 519 | "q.draw()" 520 | ] 521 | }, 522 | { 523 | "cell_type": "code", 524 | <<<<<<< HEAD 525 | "execution_count": null, 526 | "metadata": {}, 527 | "outputs": [], 528 | ======= 529 | "execution_count": 9, 530 | "metadata": {}, 531 | "outputs": [ 532 | { 533 | "name": "stdout", 534 | "output_type": "stream", 535 | "text": [ 536 | "10 enqueued\n" 537 | ] 538 | } 539 | ], 540 | >>>>>>> 8fd55a64ed3aa6820e41d3d04064e62a93184ac4 541 | "source": [ 542 | "q.enqueue(10)" 543 | ] 544 | }, 545 | { 546 | "cell_type": "code", 547 | <<<<<<< HEAD 548 | "execution_count": null, 549 | "metadata": {}, 550 | "outputs": [], 551 | ======= 552 | "execution_count": 10, 553 | "metadata": {}, 554 | "outputs": [ 555 | { 556 | "name": "stdout", 557 | "output_type": "stream", 558 | "text": [ 559 | "[2]-[3]-[6]-[10]\n" 560 | ] 561 | } 562 | ], 563 | >>>>>>> 8fd55a64ed3aa6820e41d3d04064e62a93184ac4 564 | "source": [ 565 | "q.draw()" 566 | ] 567 | }, 568 | { 569 | "cell_type": "code", 570 | <<<<<<< HEAD 571 | "execution_count": null, 572 | "metadata": {}, 573 | "outputs": [], 574 | ======= 575 | "execution_count": 11, 576 | "metadata": {}, 577 | "outputs": [ 578 | { 579 | "name": "stdout", 580 | "output_type": "stream", 581 | "text": [ 582 | "2 dequeued\n" 583 | ] 584 | }, 585 | { 586 | "data": { 587 | "text/plain": [ 588 | "2" 589 | ] 590 | }, 591 | "execution_count": 11, 592 | "metadata": {}, 593 | "output_type": "execute_result" 594 | } 595 | ], 596 | >>>>>>> 8fd55a64ed3aa6820e41d3d04064e62a93184ac4 597 | "source": [ 598 | "q.dequeue()" 599 | ] 600 | }, 601 | { 602 | "cell_type": "code", 603 | <<<<<<< HEAD 604 | "execution_count": null, 605 | "metadata": {}, 606 | "outputs": [], 607 | ======= 608 | "execution_count": 12, 609 | "metadata": {}, 610 | "outputs": [ 611 | { 612 | "name": "stdout", 613 | "output_type": "stream", 614 | "text": [ 615 | "No value supplied, nothing was enqueued.\n" 616 | ] 617 | } 618 | ], 619 | >>>>>>> 8fd55a64ed3aa6820e41d3d04064e62a93184ac4 620 | "source": [ 621 | "q.enqueue()" 622 | ] 623 | }, 624 | { 625 | "cell_type": "code", 626 | <<<<<<< HEAD 627 | "execution_count": null, 628 | "metadata": {}, 629 | "outputs": [], 630 | ======= 631 | "execution_count": 13, 632 | "metadata": {}, 633 | "outputs": [ 634 | { 635 | "name": "stdout", 636 | "output_type": "stream", 637 | "text": [ 638 | "100 enqueued\n", 639 | "101 enqueued\n", 640 | "102 enqueued\n", 641 | "103 enqueued\n", 642 | "[3]-[6]-[10]-[100]-[101]-[102]-[103]\n" 643 | ] 644 | } 645 | ], 646 | >>>>>>> 8fd55a64ed3aa6820e41d3d04064e62a93184ac4 647 | "source": [ 648 | "for i in range(100,104):\n", 649 | " q.enqueue(i)\n", 650 | "q.draw()" 651 | ] 652 | }, 653 | { 654 | "cell_type": "code", 655 | <<<<<<< HEAD 656 | "execution_count": null, 657 | "metadata": {}, 658 | "outputs": [], 659 | ======= 660 | "execution_count": 14, 661 | "metadata": {}, 662 | "outputs": [ 663 | { 664 | "name": "stdout", 665 | "output_type": "stream", 666 | "text": [ 667 | "3 dequeued\n", 668 | "6 dequeued\n", 669 | "10 dequeued\n", 670 | "[100]-[101]-[102]-[103]\n" 671 | ] 672 | } 673 | ], 674 | >>>>>>> 8fd55a64ed3aa6820e41d3d04064e62a93184ac4 675 | "source": [ 676 | "for i in range(100,103):\n", 677 | " q.dequeue()\n", 678 | "q.draw()" 679 | ] 680 | }, 681 | { 682 | <<<<<<< HEAD 683 | "cell_type": "code", 684 | "execution_count": null, 685 | "metadata": {}, 686 | "outputs": [], 687 | "source": [] 688 | }, 689 | { 690 | ======= 691 | >>>>>>> 8fd55a64ed3aa6820e41d3d04064e62a93184ac4 692 | "cell_type": "markdown", 693 | "metadata": {}, 694 | "source": [ 695 | "## Binary Tree" 696 | ] 697 | }, 698 | { 699 | "cell_type": "code", 700 | <<<<<<< HEAD 701 | "execution_count": 51, 702 | ======= 703 | "execution_count": 15, 704 | >>>>>>> 8fd55a64ed3aa6820e41d3d04064e62a93184ac4 705 | "metadata": {}, 706 | "outputs": [], 707 | "source": [ 708 | "class Node(object):\n", 709 | " def __init__(self,data=None):\n", 710 | " self.left = None\n", 711 | " self.right = None\n", 712 | " self.data = data\n", 713 | " \n", 714 | " def printNode(self):\n", 715 | " print(self.data)\n", 716 | " \n", 717 | " def insert(self, data):\n", 718 | " if self.data:\n", 719 | " if data < self.data:\n", 720 | " if self.left is None:\n", 721 | " self.left = Node(data)\n", 722 | " else:\n", 723 | " self.left.insert(data)\n", 724 | " elif data > self.data:\n", 725 | " if self.right is None:\n", 726 | " self.right = Node(data)\n", 727 | " else:\n", 728 | " self.right.insert(data)\n", 729 | " else:\n", 730 | " self.data = data\n", 731 | " \n", 732 | " def PrintTree(self):\n", 733 | " if self.left:\n", 734 | " self.left.PrintTree()\n", 735 | " print( self.data),\n", 736 | " if self.right:\n", 737 | " self.right.PrintTree()" 738 | ] 739 | }, 740 | { 741 | "cell_type": "code", 742 | <<<<<<< HEAD 743 | "execution_count": 52, 744 | ======= 745 | "execution_count": 16, 746 | >>>>>>> 8fd55a64ed3aa6820e41d3d04064e62a93184ac4 747 | "metadata": {}, 748 | "outputs": [], 749 | "source": [ 750 | "bst=Node(10)" 751 | ] 752 | }, 753 | { 754 | "cell_type": "code", 755 | <<<<<<< HEAD 756 | "execution_count": 53, 757 | ======= 758 | "execution_count": 17, 759 | >>>>>>> 8fd55a64ed3aa6820e41d3d04064e62a93184ac4 760 | "metadata": {}, 761 | "outputs": [ 762 | { 763 | "data": { 764 | "text/plain": [ 765 | <<<<<<< HEAD 766 | "<__main__.Node at 0x1658c0b9198>" 767 | ] 768 | }, 769 | "execution_count": 53, 770 | ======= 771 | "<__main__.Node at 0x165b0b61048>" 772 | ] 773 | }, 774 | "execution_count": 17, 775 | >>>>>>> 8fd55a64ed3aa6820e41d3d04064e62a93184ac4 776 | "metadata": {}, 777 | "output_type": "execute_result" 778 | } 779 | ], 780 | "source": [ 781 | "bst" 782 | ] 783 | }, 784 | { 785 | "cell_type": "code", 786 | <<<<<<< HEAD 787 | "execution_count": 54, 788 | ======= 789 | "execution_count": 18, 790 | >>>>>>> 8fd55a64ed3aa6820e41d3d04064e62a93184ac4 791 | "metadata": {}, 792 | "outputs": [ 793 | { 794 | "name": "stdout", 795 | "output_type": "stream", 796 | "text": [ 797 | "10\n" 798 | ] 799 | } 800 | ], 801 | "source": [ 802 | "bst.printNode()" 803 | ] 804 | }, 805 | { 806 | "cell_type": "code", 807 | <<<<<<< HEAD 808 | "execution_count": 55, 809 | ======= 810 | "execution_count": 19, 811 | >>>>>>> 8fd55a64ed3aa6820e41d3d04064e62a93184ac4 812 | "metadata": {}, 813 | "outputs": [], 814 | "source": [ 815 | "bst.insert(6)" 816 | ] 817 | }, 818 | { 819 | "cell_type": "code", 820 | <<<<<<< HEAD 821 | "execution_count": 56, 822 | ======= 823 | "execution_count": 20, 824 | >>>>>>> 8fd55a64ed3aa6820e41d3d04064e62a93184ac4 825 | "metadata": {}, 826 | "outputs": [ 827 | { 828 | "data": { 829 | "text/plain": [ 830 | "6" 831 | ] 832 | }, 833 | <<<<<<< HEAD 834 | "execution_count": 56, 835 | ======= 836 | "execution_count": 20, 837 | >>>>>>> 8fd55a64ed3aa6820e41d3d04064e62a93184ac4 838 | "metadata": {}, 839 | "output_type": "execute_result" 840 | } 841 | ], 842 | "source": [ 843 | "bst.left.data" 844 | ] 845 | }, 846 | { 847 | "cell_type": "code", 848 | <<<<<<< HEAD 849 | "execution_count": 57, 850 | ======= 851 | "execution_count": 21, 852 | >>>>>>> 8fd55a64ed3aa6820e41d3d04064e62a93184ac4 853 | "metadata": {}, 854 | "outputs": [], 855 | "source": [ 856 | "bst.insert(2)" 857 | ] 858 | }, 859 | { 860 | "cell_type": "code", 861 | <<<<<<< HEAD 862 | "execution_count": 58, 863 | ======= 864 | "execution_count": 22, 865 | >>>>>>> 8fd55a64ed3aa6820e41d3d04064e62a93184ac4 866 | "metadata": {}, 867 | "outputs": [ 868 | { 869 | "name": "stdout", 870 | "output_type": "stream", 871 | "text": [ 872 | "2\n", 873 | "6\n", 874 | "10\n" 875 | ] 876 | } 877 | ], 878 | "source": [ 879 | "bst.PrintTree()" 880 | ] 881 | <<<<<<< HEAD 882 | }, 883 | { 884 | "cell_type": "code", 885 | "execution_count": null, 886 | "metadata": {}, 887 | "outputs": [], 888 | "source": [] 889 | }, 890 | { 891 | "cell_type": "code", 892 | "execution_count": null, 893 | "metadata": {}, 894 | "outputs": [], 895 | "source": [] 896 | ======= 897 | >>>>>>> 8fd55a64ed3aa6820e41d3d04064e62a93184ac4 898 | } 899 | ], 900 | "metadata": { 901 | "kernelspec": { 902 | "display_name": "Python 3", 903 | "language": "python", 904 | "name": "python3" 905 | }, 906 | "language_info": { 907 | "codemirror_mode": { 908 | "name": "ipython", 909 | "version": 3 910 | }, 911 | "file_extension": ".py", 912 | "mimetype": "text/x-python", 913 | "name": "python", 914 | "nbconvert_exporter": "python", 915 | "pygments_lexer": "ipython3", 916 | "version": "3.6.2" 917 | }, 918 | "latex_envs": { 919 | "LaTeX_envs_menu_present": true, 920 | "autoclose": false, 921 | "autocomplete": true, 922 | "bibliofile": "biblio.bib", 923 | "cite_by": "apalike", 924 | "current_citInitial": 1, 925 | "eqLabelWithNumbers": true, 926 | "eqNumInitial": 1, 927 | "hotkeys": { 928 | "equation": "Ctrl-E", 929 | "itemize": "Ctrl-I" 930 | }, 931 | "labels_anchors": false, 932 | "latex_user_defs": false, 933 | "report_style_numbering": false, 934 | "user_envs_cfg": false 935 | } 936 | }, 937 | "nbformat": 4, 938 | "nbformat_minor": 2 939 | } 940 | -------------------------------------------------------------------------------- /Data Structures/Stack-Queue-using-List.py: -------------------------------------------------------------------------------- 1 | class Stack: 2 | """ 3 | Stack data structure using list 4 | """ 5 | def __init__(self,value): 6 | """ 7 | Class initializer: Produces a stack with a single value or a list of values 8 | """ 9 | self._items = [] 10 | if type(value)==list: 11 | for v in value: 12 | self._items.append(v) 13 | self._height = len(value) 14 | else: 15 | self._items.append(value) 16 | self._height = 1 17 | 18 | def pop(self): 19 | if self._height == 0: 20 | print ("Stack is empty. Nothing to pop.") 21 | return None 22 | else: 23 | self._height -=1 24 | return self._items.pop() 25 | 26 | def push(self,value): 27 | self._height +=1 28 | self._items.append(value) 29 | 30 | def isEmpty(self): 31 | return self._height==0 32 | 33 | def draw(self): 34 | if self.isEmpty(): 35 | pass 36 | return None 37 | else: 38 | n=self._height 39 | print('['+str(self._items[n-1])+']') 40 | for i in range(n-2,-1,-1): 41 | print(" | ") 42 | print('['+str(self._items[i])+']') 43 | 44 | ###============================================================================================== 45 | 46 | class Queue: 47 | """ 48 | Queue data structure using list 49 | """ 50 | def __init__(self,value): 51 | """ 52 | Class initializer: Produces a queue with a single value or a list of values 53 | """ 54 | self._items = [] 55 | if type(value)==list: 56 | for v in value: 57 | self._items.append(v) 58 | self._length = len(value) 59 | else: 60 | self._items.append(value) 61 | self._length = 1 62 | 63 | def dequeue(self): 64 | if self._length == 0: 65 | print ("Queue is empty. Nothing to dequeue.") 66 | return None 67 | else: 68 | self._length -=1 69 | return self._items.pop(0) 70 | 71 | def enqueue(self,value): 72 | self._length +=1 73 | self._items.append(value) 74 | 75 | def isEmpty(self): 76 | return self._length==0 77 | 78 | def draw(self): 79 | if self.isEmpty(): 80 | pass 81 | return None 82 | else: 83 | n=self._length 84 | for i in range(n-1): 85 | print('['+str(self._items[i])+']-',end='') 86 | print('['+str(self._items[n-1])+']') 87 | -------------------------------------------------------------------------------- /Data Structures/Stack-using-LinkedList.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Stack using Linked List" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "## Import the `LinkedList`and `Node` classes and use them to construct the `Stack` class" 15 | ] 16 | }, 17 | { 18 | "cell_type": "code", 19 | "execution_count": 1, 20 | "metadata": {}, 21 | "outputs": [], 22 | "source": [ 23 | "from LinkedList import LinkedList, Node" 24 | ] 25 | }, 26 | { 27 | "cell_type": "code", 28 | "execution_count": 2, 29 | "metadata": {}, 30 | "outputs": [], 31 | "source": [ 32 | "class Stack(object):\n", 33 | " def __init__(self,top=None):\n", 34 | " self.ll = LinkedList(top)\n", 35 | "\n", 36 | " def push(self, new_node):\n", 37 | " self.ll.insert_first(new_node)\n", 38 | "\n", 39 | " def pop(self):\n", 40 | " return self.ll.delete_first()\n", 41 | " \n", 42 | " def top(self):\n", 43 | " return self.ll.head.value" 44 | ] 45 | }, 46 | { 47 | "cell_type": "code", 48 | "execution_count": 3, 49 | "metadata": {}, 50 | "outputs": [], 51 | "source": [ 52 | "s = Stack(Node(2))" 53 | ] 54 | }, 55 | { 56 | "cell_type": "code", 57 | "execution_count": 4, 58 | "metadata": {}, 59 | "outputs": [], 60 | "source": [ 61 | "s.push(Node(4))\n", 62 | "s.push(Node(6))" 63 | ] 64 | }, 65 | { 66 | "cell_type": "code", 67 | "execution_count": 5, 68 | "metadata": {}, 69 | "outputs": [ 70 | { 71 | "data": { 72 | "text/plain": [ 73 | "6" 74 | ] 75 | }, 76 | "execution_count": 5, 77 | "metadata": {}, 78 | "output_type": "execute_result" 79 | } 80 | ], 81 | "source": [ 82 | "s.top()" 83 | ] 84 | }, 85 | { 86 | "cell_type": "code", 87 | "execution_count": 6, 88 | "metadata": {}, 89 | "outputs": [ 90 | { 91 | "data": { 92 | "text/plain": [ 93 | "6" 94 | ] 95 | }, 96 | "execution_count": 6, 97 | "metadata": {}, 98 | "output_type": "execute_result" 99 | } 100 | ], 101 | "source": [ 102 | "s.pop().value" 103 | ] 104 | }, 105 | { 106 | "cell_type": "code", 107 | "execution_count": 7, 108 | "metadata": {}, 109 | "outputs": [ 110 | { 111 | "data": { 112 | "text/plain": [ 113 | "4" 114 | ] 115 | }, 116 | "execution_count": 7, 117 | "metadata": {}, 118 | "output_type": "execute_result" 119 | } 120 | ], 121 | "source": [ 122 | "s.pop().value" 123 | ] 124 | }, 125 | { 126 | "cell_type": "code", 127 | "execution_count": 8, 128 | "metadata": {}, 129 | "outputs": [ 130 | { 131 | "data": { 132 | "text/plain": [ 133 | "2" 134 | ] 135 | }, 136 | "execution_count": 8, 137 | "metadata": {}, 138 | "output_type": "execute_result" 139 | } 140 | ], 141 | "source": [ 142 | "s.pop().value" 143 | ] 144 | }, 145 | { 146 | "cell_type": "code", 147 | "execution_count": 9, 148 | "metadata": {}, 149 | "outputs": [ 150 | { 151 | "ename": "AttributeError", 152 | "evalue": "'NoneType' object has no attribute 'value'", 153 | "output_type": "error", 154 | "traceback": [ 155 | "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", 156 | "\u001b[1;31mAttributeError\u001b[0m Traceback (most recent call last)", 157 | "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0ms\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mpop\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mvalue\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", 158 | "\u001b[1;31mAttributeError\u001b[0m: 'NoneType' object has no attribute 'value'" 159 | ] 160 | } 161 | ], 162 | "source": [ 163 | "s.pop().value" 164 | ] 165 | }, 166 | { 167 | "cell_type": "markdown", 168 | "metadata": {}, 169 | "source": [ 170 | "## Implement a `show` method" 171 | ] 172 | }, 173 | { 174 | "cell_type": "code", 175 | "execution_count": 10, 176 | "metadata": {}, 177 | "outputs": [], 178 | "source": [ 179 | "class Stack(object):\n", 180 | " def __init__(self,top=None):\n", 181 | " self.ll = LinkedList(top)\n", 182 | "\n", 183 | " def push(self, new_node):\n", 184 | " self.ll.insert_first(new_node)\n", 185 | "\n", 186 | " def pop(self):\n", 187 | " return self.ll.delete_first()\n", 188 | " \n", 189 | " def top(self):\n", 190 | " return self.ll.head.value\n", 191 | " \n", 192 | " def show(self):\n", 193 | " self.ll.show()" 194 | ] 195 | }, 196 | { 197 | "cell_type": "code", 198 | "execution_count": 11, 199 | "metadata": {}, 200 | "outputs": [], 201 | "source": [ 202 | "s = Stack(Node(2))\n", 203 | "for i in [2*i for i in range(2,5)]:\n", 204 | " s.push(Node(i))" 205 | ] 206 | }, 207 | { 208 | "cell_type": "code", 209 | "execution_count": 12, 210 | "metadata": {}, 211 | "outputs": [ 212 | { 213 | "name": "stdout", 214 | "output_type": "stream", 215 | "text": [ 216 | "[8, 6, 4, 2]\n" 217 | ] 218 | } 219 | ], 220 | "source": [ 221 | "s.show()" 222 | ] 223 | }, 224 | { 225 | "cell_type": "markdown", 226 | "metadata": {}, 227 | "source": [ 228 | "## A better-looking `show` method which shows the stack in a vertical manner" 229 | ] 230 | }, 231 | { 232 | "cell_type": "code", 233 | "execution_count": 13, 234 | "metadata": {}, 235 | "outputs": [], 236 | "source": [ 237 | "class Stack(object):\n", 238 | " def __init__(self,top=None):\n", 239 | " self.ll = LinkedList(top)\n", 240 | "\n", 241 | " def push(self, new_node):\n", 242 | " self.ll.insert_first(new_node)\n", 243 | "\n", 244 | " def pop(self):\n", 245 | " return self.ll.delete_first()\n", 246 | " \n", 247 | " def top(self):\n", 248 | " return self.ll.head.value\n", 249 | " \n", 250 | " def show(self):\n", 251 | " \"\"\"\n", 252 | " Shows (prints) a linked list\n", 253 | " \"\"\"\n", 254 | " current = self.ll.head\n", 255 | " if self.ll.head:\n", 256 | " if current.next:\n", 257 | " print(self.ll.head.value,end='\\n---\\n')\n", 258 | " else:\n", 259 | " print(self.head.value,end='')\n", 260 | " while current.next:\n", 261 | " current = current.next\n", 262 | " if current.next:\n", 263 | " print(current.value,end='\\n---\\n')\n", 264 | " else:\n", 265 | " print(current.value,end='')" 266 | ] 267 | }, 268 | { 269 | "cell_type": "code", 270 | "execution_count": 14, 271 | "metadata": {}, 272 | "outputs": [], 273 | "source": [ 274 | "s = Stack(Node(2))\n", 275 | "for i in [2*i for i in range(2,5)]:\n", 276 | " s.push(Node(i))" 277 | ] 278 | }, 279 | { 280 | "cell_type": "code", 281 | "execution_count": 15, 282 | "metadata": {}, 283 | "outputs": [ 284 | { 285 | "name": "stdout", 286 | "output_type": "stream", 287 | "text": [ 288 | "8\n", 289 | "---\n", 290 | "6\n", 291 | "---\n", 292 | "4\n", 293 | "---\n", 294 | "2" 295 | ] 296 | } 297 | ], 298 | "source": [ 299 | "s.show()" 300 | ] 301 | }, 302 | { 303 | "cell_type": "code", 304 | "execution_count": 16, 305 | "metadata": {}, 306 | "outputs": [ 307 | { 308 | "data": { 309 | "text/plain": [ 310 | "8" 311 | ] 312 | }, 313 | "execution_count": 16, 314 | "metadata": {}, 315 | "output_type": "execute_result" 316 | } 317 | ], 318 | "source": [ 319 | "s.pop().value" 320 | ] 321 | }, 322 | { 323 | "cell_type": "code", 324 | "execution_count": 17, 325 | "metadata": {}, 326 | "outputs": [ 327 | { 328 | "name": "stdout", 329 | "output_type": "stream", 330 | "text": [ 331 | "6\n", 332 | "---\n", 333 | "4\n", 334 | "---\n", 335 | "2" 336 | ] 337 | } 338 | ], 339 | "source": [ 340 | "s.show()" 341 | ] 342 | } 343 | ], 344 | "metadata": { 345 | "kernelspec": { 346 | "display_name": "Python 3", 347 | "language": "python", 348 | "name": "python3" 349 | }, 350 | "language_info": { 351 | "codemirror_mode": { 352 | "name": "ipython", 353 | "version": 3 354 | }, 355 | "file_extension": ".py", 356 | "mimetype": "text/x-python", 357 | "name": "python", 358 | "nbconvert_exporter": "python", 359 | "pygments_lexer": "ipython3", 360 | "version": "3.7.0" 361 | } 362 | }, 363 | "nbformat": 4, 364 | "nbformat_minor": 4 365 | } 366 | -------------------------------------------------------------------------------- /Data Structures/Trees_class.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Tue Jan 23 13:00:12 2018 4 | 5 | @author: Tirtha 6 | """ 7 | 8 | class Tree: 9 | """ 10 | Recursive definition of Tree class plus various helper functions/methods 11 | """ 12 | def __init__(self, value, children): 13 | """ 14 | Class initializer: Produces a single root node having a specific string value; 15 | children is a list of references to the root of the children branches. 16 | Note th children are trees themselves, hence the recursion. 17 | """ 18 | self._value = value 19 | self._children = children 20 | 21 | def strep(self): 22 | """ 23 | Generates a string representation of the tree 24 | """ 25 | text = "" 26 | text+=str(self._value) 27 | 28 | for child in self._children: 29 | text+='[' 30 | text+=child.strep() 31 | text+=']' 32 | return text 33 | 34 | def get_value(self): 35 | return self._value 36 | 37 | def children(self): 38 | for child in self._children: 39 | yield child 40 | 41 | def num_nodes(self): 42 | result = 1 43 | for child in self._children: 44 | result+=child.num_nodes() 45 | return result 46 | 47 | def num_leaves(self): 48 | if len(self._children)==0: 49 | return 1 50 | else: 51 | result=0 52 | for child in self._children: 53 | result += child.num_leaves() 54 | return result 55 | 56 | def height(self): 57 | height=0 58 | for child in self._children: 59 | height = max(height,child.height()+1) 60 | return height 61 | 62 | 63 | tree_a = Tree('a',[]) 64 | tree_b = Tree('b',[]) 65 | 66 | tree_cab = Tree('c',[tree_a,tree_b]) 67 | 68 | print (tree_a.strep()) 69 | print(tree_b.get_value()) 70 | print(tree_cab.strep()) 71 | 72 | tree_4 = Tree('d',[tree_cab,tree_b,tree_a]) 73 | print (tree_4.strep()) 74 | print(tree_4.num_nodes()) 75 | print(tree_4.num_leaves()) 76 | print(tree_4.height()) 77 | 78 | 79 | OPERATORS = { 80 | "+":lambda x,y:x+y, 81 | "-":lambda x,y:x-y, 82 | "*":lambda x,y:x*y, 83 | "/":lambda x,y:x/y, 84 | "%":lambda x,y:x%y, 85 | "^":lambda x,y:x**y 86 | } 87 | 88 | class Arithmatic (Tree): 89 | def __init__(self, value, children): 90 | Tree.__init__(self, value, children) 91 | 92 | def strexp(self): 93 | if len(self._children)==0: 94 | return str(self._value) 95 | else: 96 | text='(' 97 | text+=self._children[0].strexp() 98 | text+=str(self._value) 99 | text+=self._children[1].strexp() 100 | text+=')' 101 | return text 102 | 103 | def evaluate_exp(self): 104 | if len(self._children)==0: 105 | if ('.' in self._value): 106 | return float(self._value) 107 | else: 108 | return int(self._value) 109 | else: 110 | function = OPERATORS[self._value] 111 | left_value = self._children[0].evaluate_exp() 112 | right_value = self._children[1].evaluate_exp() 113 | return function(left_value,right_value) 114 | 115 | #exp1=Arithmatic('*',[]) 116 | exp2=Arithmatic('1.2',[]) 117 | exp3=Arithmatic('5.2',[]) 118 | exp4=Arithmatic('*',[exp2,exp3]) 119 | exp5=Arithmatic('4.2',[]) 120 | exp6=Arithmatic('7.5',[]) 121 | exp7=Arithmatic('+',[exp5,exp6]) 122 | exp8=Arithmatic('/',[exp4,exp7]) 123 | exp9=Arithmatic('2',[]) 124 | exp10=Arithmatic('^',[exp9,exp8]) 125 | 126 | print("The expression is:",exp10.strexp()) 127 | print("The evluated value is:",exp10.evaluate_exp()) 128 | print("String representation is:",exp10.strep()) 129 | print("Depth of this computation graph tree is:",exp10.height()) 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Tirthajyoti Sarkar 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Popular algorithms and useful data Structures in Python 2 | 3 | ## Building useful data structures in Python 4 | * Linked List 5 | * Queue 6 | * Stack 7 | * Trees 8 | * Graph 9 | 10 | ## Coding fundamentally important algorithms 11 | * Binary search 12 | * Bubble sort 13 | * Insertion sort 14 | * Selection sort 15 | * Quick sort 16 | -------------------------------------------------------------------------------- /__pycache__/Common_data_structures_class.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tirthajyoti/Algorithm-Data-Structures-Python/bbe8bb3500e31dbceb5d569a017c210d6ec183b2/__pycache__/Common_data_structures_class.cpython-36.pyc --------------------------------------------------------------------------------