Files
udemy_data_structures/Section_2/Stacks, Queues & Heaps.ipynb

347 lines
8.4 KiB
Plaintext
Raw Permalink Normal View History

2019-05-01 22:08:49 -07:00
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Stacks, Queues & Heaps\n",
"© Joe James, 2019.\n",
"\n",
"### Stack using Python List\n",
"Stack is a LIFO data structure -- last-in, first-out. \n",
"Use append() to push an item onto the stack. \n",
"Use pop() to remove an item."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[4, 7, 12, 19]\n"
]
}
],
"source": [
"my_stack = list()\n",
"my_stack.append(4)\n",
"my_stack.append(7)\n",
"my_stack.append(12)\n",
"my_stack.append(19)\n",
"print(my_stack)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"19\n",
"12\n",
"[4, 7]\n"
]
}
],
"source": [
"print(my_stack.pop())\n",
"print(my_stack.pop())\n",
"print(my_stack)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Stack using List with a Wrapper Class\n",
"We create a Stack class and a full set of Stack methods. \n",
"But the underlying data structure is really a Python List. \n",
"For pop and peek methods we first check whether the stack is empty, to avoid exceptions."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"class Stack():\n",
" def __init__(self):\n",
" self.stack = list()\n",
" def push(self, item):\n",
" self.stack.append(item)\n",
" def pop(self):\n",
" if len(self.stack) > 0:\n",
" return self.stack.pop()\n",
" else:\n",
" return None\n",
" def peek(self):\n",
" if len(self.stack) > 0:\n",
" return self.stack[len(self.stack)-1]\n",
" else:\n",
" return None\n",
" def __str__(self):\n",
" return str(self.stack)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Test Code for Stack Wrapper Class"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[1, 3]\n",
"3\n",
"1\n",
"1\n",
"None\n"
]
}
],
"source": [
"my_stack = Stack()\n",
"my_stack.push(1)\n",
"my_stack.push(3)\n",
"print(my_stack)\n",
"print(my_stack.pop())\n",
"print(my_stack.peek())\n",
"print(my_stack.pop())\n",
"print(my_stack.pop())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"### Queue using Python Deque\n",
"Queue is a FIFO data structure -- first-in, first-out. \n",
"Deque is a double-ended queue, but we can use it for our queue. \n",
"We use append() to enqueue an item, and popleft() to dequeue an item. \n",
"See [Python docs](https://docs.python.org/3/library/collections.html#collections.deque) for deque."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"deque([5, 10])\n",
"5\n"
]
}
],
"source": [
"from collections import deque\n",
"my_queue = deque()\n",
"my_queue.append(5)\n",
"my_queue.append(10)\n",
"print(my_queue)\n",
"print(my_queue.popleft())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Fun exercise:\n",
"Write a wrapper class for the Queue class, similar to what we did for Stack, but using Python deque. \n",
"Try adding enqueue, dequeue, and get_size methods."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Python Single-ended Queue Wrapper Class using Deque\n",
"We rename the append method to enqueue, and popleft to dequeue. \n",
"We also add peek and get_size operations."
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"from collections import deque\n",
"class Queue():\n",
" def __init__(self):\n",
" self.queue = deque()\n",
" self.size = 0\n",
" def enqueue(self, item):\n",
" self.queue.append(item)\n",
" self.size += 1\n",
" def dequeue(self, item):\n",
" if self.size > 0:\n",
" self.size -= 1\n",
" return self.queue.popleft()\n",
" else: \n",
" return None\n",
" def peek(self):\n",
" if self.size > 0:\n",
" ret_val = self.queue.popleft()\n",
" queue.appendleft(ret_val)\n",
" return ret_val\n",
" else:\n",
" return None\n",
" def get_size(self):\n",
" return self.size"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Python MaxHeap\n",
"A MaxHeap always bubbles the highest value to the top, so it can be removed instantly. \n",
"Public functions: push, peek, pop \n",
"Private functions: __swap, __floatUp, __bubbleDown, __str__."
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [],
"source": [
"class MaxHeap:\n",
" def __init__(self, items=[]):\n",
" super().__init__()\n",
" self.heap = [0]\n",
" for item in items:\n",
" self.heap.append(item)\n",
" self.__floatUp(len(self.heap) - 1)\n",
"\n",
" def push(self, data):\n",
" self.heap.append(data)\n",
" self.__floatUp(len(self.heap) - 1)\n",
"\n",
" def peek(self):\n",
" if self.heap[1]:\n",
" return self.heap[1]\n",
" else:\n",
" return False\n",
" \n",
" def pop(self):\n",
" if len(self.heap) > 2:\n",
" self.__swap(1, len(self.heap) - 1)\n",
" max = self.heap.pop()\n",
" self.__bubbleDown(1)\n",
" elif len(self.heap) == 2:\n",
" max = self.heap.pop()\n",
" else: \n",
" max = False\n",
" return max\n",
"\n",
" def __swap(self, i, j):\n",
" self.heap[i], self.heap[j] = self.heap[j], self.heap[i]\n",
"\n",
" def __floatUp(self, index):\n",
" parent = index//2\n",
" if index <= 1:\n",
" return\n",
" elif self.heap[index] > self.heap[parent]:\n",
" self.__swap(index, parent)\n",
" self.__floatUp(parent)\n",
"\n",
" def __bubbleDown(self, index):\n",
" left = index * 2\n",
" right = index * 2 + 1\n",
" largest = index\n",
" if len(self.heap) > left and self.heap[largest] < self.heap[left]:\n",
" largest = left\n",
" if len(self.heap) > right and self.heap[largest] < self.heap[right]:\n",
" largest = right\n",
" if largest != index:\n",
" self.__swap(index, largest)\n",
" self.__bubbleDown(largest)\n",
" \n",
" def __str__(self):\n",
" return str(self.heap)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### MaxHeap Test Code"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[0, 95, 10, 21, 3]\n",
"95\n",
"21\n"
]
}
],
"source": [
"m = MaxHeap([95, 3, 21])\n",
"m.push(10)\n",
"print(m)\n",
"print(m.pop())\n",
"print(m.peek())"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.0"
}
},
"nbformat": 4,
"nbformat_minor": 2
}