initial upload of all course files
This commit is contained in:
283
Section_1/List Comprehensions.ipynb
Normal file
283
Section_1/List Comprehensions.ipynb
Normal file
@@ -0,0 +1,283 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Python List Comprehensions\n",
|
||||
"basic format: new_list = [transform sequence [filter] ] \n",
|
||||
"© Joe James, 2019."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import random"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**get values within a range**"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"under_10: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"under_10 = [x for x in range(10)]\n",
|
||||
"print('under_10: ' + str(under_10))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**get squared values**"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"squares: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"squares = [x**2 for x in under_10]\n",
|
||||
"print('squares: ' + str(squares))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**get odd numbers using mod**"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"odds: [1, 3, 5, 7, 9]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"odds = [x for x in range(10) if x%2 == 1]\n",
|
||||
"print('odds: ' + str(odds))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**get multiples of 10**"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"ten_x: [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"ten_x = [x * 10 for x in range(10)]\n",
|
||||
"print('ten_x: ' + str(ten_x))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**get all numbers from a string**"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"nums: 2073\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"s = 'I love 2 go t0 the store 7 times a w3ek.'\n",
|
||||
"nums = [x for x in s if x.isnumeric()]\n",
|
||||
"print('nums: ' + ''.join(nums))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**get index of a list item**"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"index = 2\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"names = ['Cosmo', 'Pedro', 'Anu', 'Ray']\n",
|
||||
"idx = [k for k, v in enumerate(names) if v == 'Anu']\n",
|
||||
"print('index = ' + str(idx[0]))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**delete an item from a list**"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"['D', 'F', 'E', 'A', 'B', 'C'] ['D', 'F', 'E', 'A', 'B']\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"letters = [x for x in 'ABCDEF']\n",
|
||||
"random.shuffle(letters)\n",
|
||||
"letrs = [a for a in letters if a != 'C']\n",
|
||||
"print(letters, letrs)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**if-else condition in a comprehension** \n",
|
||||
"must come before iteration."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 9,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"new list: [50, 30, 10, 18, 6, 70]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"nums = [5, 3, 10, 18, 6, 7]\n",
|
||||
"new_list = [x if x%2 == 0 else 10*x for x in nums]\n",
|
||||
"print('new list: ' + str(new_list))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**nested loop iteration for 2D list** \n",
|
||||
"b is the subsets, x is the values."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 10,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"[1, 2, 3, 4]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"a = [[1,2],[3,4]]\n",
|
||||
"new_list = [x for b in a for x in b]\n",
|
||||
"print(new_list)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"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
|
||||
}
|
||||
1215
Section_1/Python Data Structures.ipynb
Normal file
1215
Section_1/Python Data Structures.ipynb
Normal file
File diff suppressed because it is too large
Load Diff
BIN
Section_1/Python_native-data-structures.pdf
Normal file
BIN
Section_1/Python_native-data-structures.pdf
Normal file
Binary file not shown.
BIN
Section_2/MaxHeap.pdf
Normal file
BIN
Section_2/MaxHeap.pdf
Normal file
Binary file not shown.
BIN
Section_2/Stacks and Queues.pdf
Normal file
BIN
Section_2/Stacks and Queues.pdf
Normal file
Binary file not shown.
346
Section_2/Stacks, Queues & Heaps.ipynb
Normal file
346
Section_2/Stacks, Queues & Heaps.ipynb
Normal file
@@ -0,0 +1,346 @@
|
||||
{
|
||||
"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
|
||||
}
|
||||
439
Section_3/Python Linked Lists.ipynb
Normal file
439
Section_3/Python Linked Lists.ipynb
Normal file
@@ -0,0 +1,439 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Python Linked Lists"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Node Class\n",
|
||||
"Node class has a constructor that sets the data passed in, and optionally can set the next_node and prev_node. \n",
|
||||
"It also has a str method to give a string representation for printing. \n",
|
||||
"Note that prev_node is only used for Doubly Linked Lists."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 128,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"class Node:\n",
|
||||
"\n",
|
||||
" def __init__ (self, d, n=None, p=None):\n",
|
||||
" self.data = d\n",
|
||||
" self.next_node = n\n",
|
||||
" self.prev_node = p\n",
|
||||
" \n",
|
||||
" def __str__ (self):\n",
|
||||
" return ('(' + str(self.data) + ')')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### LinkedList Class\n",
|
||||
"A LinkedList object has two attributes: a root node that defaults to None, and size that defaults to 0.\n",
|
||||
" \n",
|
||||
"**Add** method receives a piece of data, creates a new Node, setting the root as its next_node, changes the LL's root pointer to the new node, and increments size.\n",
|
||||
"\n",
|
||||
"**Find** iterates through the nodes until it finds the data passed in. If if finds the data it will return it, otherwise returns None.\n",
|
||||
"\n",
|
||||
"**Remove** needs pointers to this_node and prev_node. If it finds the data, it needs to check if it is in the root node (prev_node is None) before deciding how to bypass the deleted node.\n",
|
||||
"\n",
|
||||
"**Print_list** iterates the list and prints each node."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 129,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"class LinkedList:\n",
|
||||
"\n",
|
||||
" def __init__(self, r = None):\n",
|
||||
" self.root = r\n",
|
||||
" self.size = 0\n",
|
||||
"\n",
|
||||
" def add(self, d):\n",
|
||||
" new_node = Node(d, self.root)\n",
|
||||
" self.root = new_node\n",
|
||||
" self.size += 1\n",
|
||||
" \n",
|
||||
" def find(self, d):\n",
|
||||
" this_node = self.root\n",
|
||||
" while this_node is not None:\n",
|
||||
" if this_node.data == d:\n",
|
||||
" return d\n",
|
||||
" else:\n",
|
||||
" this_node = this_node.next_node\n",
|
||||
" return None\n",
|
||||
"\n",
|
||||
" def remove(self, d):\n",
|
||||
" this_node = self.root\n",
|
||||
" prev_node = None\n",
|
||||
"\n",
|
||||
" while this_node is not None:\n",
|
||||
" if this_node.data == d:\n",
|
||||
" if prev_node is not None: # data is in non-root\n",
|
||||
" prev_node.next_node = this_node.next_node\n",
|
||||
" else: # data is in root node\n",
|
||||
" self.root = this_node.next_node\n",
|
||||
" self.size -= 1\n",
|
||||
" return True # data removed\n",
|
||||
" else:\n",
|
||||
" prev_node = this_node\n",
|
||||
" this_node = this_node.next_node\n",
|
||||
" return False # data not found\n",
|
||||
" \n",
|
||||
" def print_list(self):\n",
|
||||
" this_node = self.root\n",
|
||||
" while this_node is not None:\n",
|
||||
" print(this_node, end='->')\n",
|
||||
" this_node = this_node.next_node\n",
|
||||
" print('None')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Linked List Test Code\n",
|
||||
"This test code adds nodes to the LinkedList, Prints the list, prints the size, removes an item, and finds an item."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 130,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"(12)->(8)->(5)->None\n",
|
||||
"size=3\n",
|
||||
"size=2\n",
|
||||
"5\n",
|
||||
"(12)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"myList = LinkedList()\n",
|
||||
"myList.add(5)\n",
|
||||
"myList.add(8)\n",
|
||||
"myList.add(12)\n",
|
||||
"myList.print_list()\n",
|
||||
"\n",
|
||||
"print(\"size=\"+str(myList.size))\n",
|
||||
"myList.remove(8)\n",
|
||||
"print(\"size=\"+str(myList.size))\n",
|
||||
"print(myList.find(5))\n",
|
||||
"print(myList.root)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"-----\n",
|
||||
"### Circular Linked List\n",
|
||||
"Includes attributes root and size. \n",
|
||||
"Includes methods add, find, remove, and print_list."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 131,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"class CircularLinkedList:\n",
|
||||
"\n",
|
||||
" def __init__ (self, r = None):\n",
|
||||
" self.root = r\n",
|
||||
" self.size = 0\n",
|
||||
"\n",
|
||||
" def add (self, d):\n",
|
||||
" if self.size == 0:\n",
|
||||
" self.root = Node(d)\n",
|
||||
" self.root.next_node = self.root\n",
|
||||
" else:\n",
|
||||
" new_node = Node (d, self.root.next_node)\n",
|
||||
" self.root.next_node = new_node\n",
|
||||
" self.size += 1\n",
|
||||
"\n",
|
||||
" def find (self, d):\n",
|
||||
" this_node = self.root\n",
|
||||
" while True:\n",
|
||||
" if this_node.data == d:\n",
|
||||
" return d\n",
|
||||
" elif this_node.next_node == self.root:\n",
|
||||
" return False\n",
|
||||
" this_node = this_node.next_node\n",
|
||||
"\n",
|
||||
" def remove (self, d):\n",
|
||||
" this_node = self.root\n",
|
||||
" prev_node = None\n",
|
||||
"\n",
|
||||
" while True:\n",
|
||||
" if this_node.data == d: # found\n",
|
||||
" if prev_node is not None:\n",
|
||||
" prev_node.next_node = this_node.next_node\n",
|
||||
" else:\n",
|
||||
" while this_node.next_node != self.root:\n",
|
||||
" this_node = this_node.next_node\n",
|
||||
" this_node.next_node = self.root.next_node\n",
|
||||
" self.root = self.root.next_node\n",
|
||||
" self.size -= 1\n",
|
||||
" return True # data removed\n",
|
||||
" elif this_node.next_node == self.root:\n",
|
||||
" return False # data not found\n",
|
||||
" prev_node = this_node\n",
|
||||
" this_node = this_node.next_node\n",
|
||||
" \n",
|
||||
" def print_list (self):\n",
|
||||
" if self.root is None:\n",
|
||||
" return\n",
|
||||
" this_node = self.root\n",
|
||||
" print (this_node, end='->')\n",
|
||||
" while this_node.next_node != self.root:\n",
|
||||
" this_node = this_node.next_node\n",
|
||||
" print (this_node, end='->')\n",
|
||||
" print()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Circular Linked List Test Code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 132,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"size=5\n",
|
||||
"8\n",
|
||||
"False\n",
|
||||
"(5)->(9)->(8)->(3)->(7)->(5)->(9)->(8)->(3)->\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"cll = CircularLinkedList()\n",
|
||||
"for i in [5, 7, 3, 8, 9]:\n",
|
||||
" cll.add(i)\n",
|
||||
"\n",
|
||||
"print(\"size=\"+str(cll.size))\n",
|
||||
"print(cll.find(8))\n",
|
||||
"print(cll.find(12))\n",
|
||||
"\n",
|
||||
"my_node = cll.root\n",
|
||||
"print (my_node, end='->')\n",
|
||||
"for i in range(8):\n",
|
||||
" my_node = my_node.next_node\n",
|
||||
" print (my_node, end='->')\n",
|
||||
"print()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 133,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"(5)->(9)->(8)->(3)->(7)->\n",
|
||||
"False\n",
|
||||
"size=4\n",
|
||||
"(9)->(3)->(7)->\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"cll.print_list()\n",
|
||||
"cll.remove(8)\n",
|
||||
"print(cll.remove(15))\n",
|
||||
"print(\"size=\"+str(cll.size))\n",
|
||||
"cll.remove(5) # delete root node\n",
|
||||
"cll.print_list()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"-----\n",
|
||||
"### Doubly Linked List"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 134,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"class DoublyLinkedList:\n",
|
||||
"\n",
|
||||
" def __init__ (self, r = None):\n",
|
||||
" self.root = r\n",
|
||||
" self.last = r\n",
|
||||
" self.size = 0\n",
|
||||
"\n",
|
||||
" def add (self, d):\n",
|
||||
" if self.size == 0:\n",
|
||||
" self.root = Node(d)\n",
|
||||
" self.last = self.root\n",
|
||||
" else:\n",
|
||||
" new_node = Node(d, self.root)\n",
|
||||
" self.root.prev_node = new_node\n",
|
||||
" self.root = new_node\n",
|
||||
" self.size += 1\n",
|
||||
"\n",
|
||||
" def find (self, d):\n",
|
||||
" this_node = self.root\n",
|
||||
" while this_node is not None:\n",
|
||||
" if this_node.data == d:\n",
|
||||
" return d\n",
|
||||
" elif this_node.next_node == None:\n",
|
||||
" return False\n",
|
||||
" else:\n",
|
||||
" this_node = this_node.next_node\n",
|
||||
"\n",
|
||||
" def remove (self, d):\n",
|
||||
" this_node = self.root\n",
|
||||
" while this_node is not None:\n",
|
||||
" if this_node.data == d:\n",
|
||||
" if this_node.prev_node is not None:\n",
|
||||
" if this_node.next_node is not None: # delete a middle node\n",
|
||||
" this_node.prev_node.next_node = this_node.next_node\n",
|
||||
" this_node.next_node.prev_node = this_node.prev_node\n",
|
||||
" else: # delete last node\n",
|
||||
" this_node.prev_node.next_node = None\n",
|
||||
" self.last = this_node.prev_node\n",
|
||||
" else: # delete root node\n",
|
||||
" self.root = this_node.next_node\n",
|
||||
" this_node.next_node.prev_node = self.root\n",
|
||||
" self.size -= 1\n",
|
||||
" return True # data removed\n",
|
||||
" else:\n",
|
||||
" this_node = this_node.next_node\n",
|
||||
" return False # data not found\n",
|
||||
" \n",
|
||||
" def print_list (self):\n",
|
||||
" if self.root is None:\n",
|
||||
" return\n",
|
||||
" this_node = self.root\n",
|
||||
" print (this_node, end='->')\n",
|
||||
" while this_node.next_node is not None:\n",
|
||||
" this_node = this_node.next_node\n",
|
||||
" print (this_node, end='->')\n",
|
||||
" print()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Doubly Linked List Test Code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 135,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"size=5\n",
|
||||
"(9)->(8)->(3)->(9)->(5)->\n",
|
||||
"size=4\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"dll = DoublyLinkedList()\n",
|
||||
"for i in [5, 9, 3, 8, 9]:\n",
|
||||
" dll.add(i)\n",
|
||||
"\n",
|
||||
"print(\"size=\"+str(dll.size))\n",
|
||||
"dll.print_list()\n",
|
||||
"dll.remove(8)\n",
|
||||
"print(\"size=\"+str(dll.size))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 136,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"False\n",
|
||||
"False\n",
|
||||
"(22)->(21)->(9)->(3)->(9)->\n",
|
||||
"(3)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(dll.remove(15))\n",
|
||||
"print(dll.find(15))\n",
|
||||
"dll.add(21)\n",
|
||||
"dll.add(22)\n",
|
||||
"dll.remove(5)\n",
|
||||
"dll.print_list()\n",
|
||||
"print(dll.last.prev_node)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"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
|
||||
}
|
||||
BIN
Section_3/Python Linked Lists.pdf
Normal file
BIN
Section_3/Python Linked Lists.pdf
Normal file
Binary file not shown.
148
Section_4/Binary Search Tree.ipynb
Normal file
148
Section_4/Binary Search Tree.ipynb
Normal file
@@ -0,0 +1,148 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Binary Search Tree\n",
|
||||
"**Constructor** sets three attributes: data, left subtree and right subtree. \n",
|
||||
"**Insert** inserts a new subtree into the proper location. \n",
|
||||
"**Find** finds a value. If value not found, returns False. \n",
|
||||
"**Get_size** returns the number of nodes in the tree (excluding None nodes). \n",
|
||||
"**Preorder** prints a preorder traversal of the tree. \n",
|
||||
"**Inorder** prints an inorder traversal of the tree."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 69,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"class Tree:\n",
|
||||
" def __init__(self, data, left=None, right=None):\n",
|
||||
" self.data = data\n",
|
||||
" self.left = left\n",
|
||||
" self.right = right\n",
|
||||
" def insert(self, data):\n",
|
||||
" if self.data == data:\n",
|
||||
" return False # duplicate value\n",
|
||||
" elif self.data > data:\n",
|
||||
" if self.left is not None:\n",
|
||||
" return self.left.insert(data)\n",
|
||||
" else:\n",
|
||||
" self.left = Tree(data)\n",
|
||||
" return True\n",
|
||||
" else:\n",
|
||||
" if self.right is not None:\n",
|
||||
" return self.right.insert(data)\n",
|
||||
" else:\n",
|
||||
" self.right = Tree(data)\n",
|
||||
" return True\n",
|
||||
" def find(self, data):\n",
|
||||
" if self.data == data:\n",
|
||||
" return data\n",
|
||||
" elif self.data > data:\n",
|
||||
" if self.left is None:\n",
|
||||
" return False\n",
|
||||
" else:\n",
|
||||
" return self.left.find(data)\n",
|
||||
" elif self.data < data:\n",
|
||||
" if self.right is None:\n",
|
||||
" return False\n",
|
||||
" else:\n",
|
||||
" return self.right.find(data)\n",
|
||||
" def get_size(self):\n",
|
||||
" if self.left is not None and self.right is not None:\n",
|
||||
" return 1 + self.left.get_size() + self.right.get_size()\n",
|
||||
" elif self.left:\n",
|
||||
" return 1 + self.left.get_size()\n",
|
||||
" elif self.right:\n",
|
||||
" return 1 + self.right.get_size()\n",
|
||||
" else:\n",
|
||||
" return 1\n",
|
||||
" def preorder(self):\n",
|
||||
" if self is not None:\n",
|
||||
" print (self.data, end=' ')\n",
|
||||
" if self.left is not None:\n",
|
||||
" self.left.preorder()\n",
|
||||
" if self.right:\n",
|
||||
" self.right.preorder()\n",
|
||||
" def inorder(self):\n",
|
||||
" if self is not None:\n",
|
||||
" if self.left is not None:\n",
|
||||
" self.left.inorder()\n",
|
||||
" print (self.data, end=' ')\n",
|
||||
" if self.right is not None:\n",
|
||||
" self.right.inorder()\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Test Code\n",
|
||||
"We create a new tree, insert one value, insert a whole list of values, find all values from 1 to 15 (False for 0, 5 and 8 shows that those values are not in the tree), print the size of the tree, print preorder and postorder traversals."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 70,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"False 1 2 3 4 False 6 7 False 9 10 11 12 13 14 15 \n",
|
||||
" 13\n",
|
||||
"7 2 1 3 6 4 9 15 10 12 11 13 14 \n",
|
||||
"1 2 3 4 6 7 9 10 11 12 13 14 15 \n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"tree = Tree(7)\n",
|
||||
"tree.insert(9)\n",
|
||||
"for i in [15, 10, 2, 12, 3, 1, 13, 6, 11, 4, 14, 9]:\n",
|
||||
" tree.insert(i)\n",
|
||||
"for i in range(16):\n",
|
||||
" print(tree.find(i), end=' ')\n",
|
||||
"print('\\n', tree.get_size())\n",
|
||||
"\n",
|
||||
"tree.preorder()\n",
|
||||
"print()\n",
|
||||
"tree.inorder()\n",
|
||||
"print()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"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
|
||||
}
|
||||
BIN
Section_4/Binary Search Trees.pdf
Normal file
BIN
Section_4/Binary Search Trees.pdf
Normal file
Binary file not shown.
170
Section_5/Graph Implementation Using Adjacency Lists.ipynb
Normal file
170
Section_5/Graph Implementation Using Adjacency Lists.ipynb
Normal file
@@ -0,0 +1,170 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Graph Implementation Using Adjacency Lists\n",
|
||||
"for an undirected graph. \n",
|
||||
"© Joe James, 2019."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Vertex Class\n",
|
||||
"The Vertex class has a constructor that sets the name of the vertex (in our example, just a letter), and creates a new empty set to store neighbors.\n",
|
||||
"\n",
|
||||
"The add_neighbor method adds the name of a neighboring vertex to the neighbors set. This set automatically eliminates duplicates."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 25,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"class Vertex:\n",
|
||||
" def __init__(self, n):\n",
|
||||
" self.name = n\n",
|
||||
" self.neighbors = set()\n",
|
||||
" \n",
|
||||
" def add_neighbor(self, v):\n",
|
||||
" self.neighbors.add(v)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Graph Class\n",
|
||||
"The Graph class uses a dictionary to store vertices in the format, vertex_name:vertex_object.\n",
|
||||
" \n",
|
||||
"Adding a new vertex to the graph, we first check if the object passed in is a vertex object, then we check if it already exists in the graph. If both checks pass, then we add the vertex to the graph's vertices dictionary.\n",
|
||||
"\n",
|
||||
"When adding an edge, we receive two vertex names, we first check if both vertex names are valid, then we add each to the other's neighbors set.\n",
|
||||
"\n",
|
||||
"To print the graph, we iterate through the vertices, and print each vertex name (the key) followed by its sorted neighbors list."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 26,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"class Graph:\n",
|
||||
" vertices = {}\n",
|
||||
" \n",
|
||||
" def add_vertex(self, vertex):\n",
|
||||
" if isinstance(vertex, Vertex) and vertex.name not in self.vertices:\n",
|
||||
" self.vertices[vertex.name] = vertex\n",
|
||||
" return True\n",
|
||||
" else:\n",
|
||||
" return False\n",
|
||||
" \n",
|
||||
" def add_edge(self, u, v):\n",
|
||||
" if u in self.vertices and v in self.vertices:\n",
|
||||
" self.vertices[u].add_neighbor(v)\n",
|
||||
" self.vertices[v].add_neighbor(u)\n",
|
||||
" return True\n",
|
||||
" else:\n",
|
||||
" return False\n",
|
||||
" \n",
|
||||
" def print_graph(self):\n",
|
||||
" for key in sorted(list(self.vertices.keys())):\n",
|
||||
" print(key, sorted(list(self.vertices[key].neighbors)))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Test Code\n",
|
||||
"Here we create a new Graph object. We create a new vertex named A. We add A to the graph. Then we add new vertex B to the graph. Then we iterate from A to K and add a bunch of vertices to the graph. Since the add_vertex method checks for duplicates, A and B are not added twice."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 27,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"g = Graph()\n",
|
||||
"a = Vertex('A')\n",
|
||||
"g.add_vertex(a)\n",
|
||||
"g.add_vertex(Vertex('B'))\n",
|
||||
"for i in range(ord('A'), ord('K')):\n",
|
||||
" g.add_vertex(Vertex(chr(i)))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"An edge consists of two vertex names. Here we iterate through a list of edges and add each to the graph. \n",
|
||||
"\n",
|
||||
"This print_graph method doesn't give a very good visualization of the graph, but it does show the neighbors for each vertex."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 28,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"A ['B', 'E']\n",
|
||||
"B ['A', 'F']\n",
|
||||
"C ['G']\n",
|
||||
"D ['E', 'H']\n",
|
||||
"E ['A', 'D', 'H']\n",
|
||||
"F ['B', 'G', 'I', 'J']\n",
|
||||
"G ['C', 'F', 'J']\n",
|
||||
"H ['D', 'E', 'I']\n",
|
||||
"I ['F', 'H']\n",
|
||||
"J ['F', 'G']\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"edges = ['AB', 'AE', 'BF', 'CG', 'DE', 'DH', 'EH', 'FG', 'FI', 'FJ', 'GJ', 'HI']\n",
|
||||
"for edge in edges:\n",
|
||||
" g.add_edge(edge[0], edge[1])\n",
|
||||
"\n",
|
||||
"g.print_graph()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"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
|
||||
}
|
||||
175
Section_5/Graph Implementation Using Adjacency Matrix.ipynb
Normal file
175
Section_5/Graph Implementation Using Adjacency Matrix.ipynb
Normal file
@@ -0,0 +1,175 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Graph Implementation Using Adjacency Matrix\n",
|
||||
"for undirected graph, with weighted or unweighted edges. \n",
|
||||
"© Joe James, 2019."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Vertex Class\n",
|
||||
"A vertex object only needs to store its name. "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"class Vertex:\n",
|
||||
" def __init__(self, n):\n",
|
||||
" self.name = n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Graph Class\n",
|
||||
"A graph object has three attributes: \n",
|
||||
"**vertices** - a dictionary with vertex_name:vertex_object. \n",
|
||||
"**edges** - a 2-dimensional list (ie. a matrix) of edges. for an unweighted graph it will contain 0 for no edge and 1 for edge. \n",
|
||||
"**edge_indices** - a dictionary with vertex_name:list_index (eg. A:0) to access edges. \n",
|
||||
"add_vertex updates all three of these attributes. \n",
|
||||
"add_edge only needs to update the edges matrix."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"class Graph:\n",
|
||||
" vertices = {}\n",
|
||||
" edges = []\n",
|
||||
" edge_indices = {}\n",
|
||||
" \n",
|
||||
" def add_vertex(self, vertex):\n",
|
||||
" if isinstance(vertex, Vertex) and vertex.name not in self.vertices:\n",
|
||||
" self.vertices[vertex.name] = vertex\n",
|
||||
" # for loop appends a column of zeros to the edges matrix\n",
|
||||
" for row in self.edges:\n",
|
||||
" row.append(0)\n",
|
||||
" # append a row of zeros to the bottom of the edges matrix\n",
|
||||
" self.edges.append([0] * (len(self.edges)+1))\n",
|
||||
" self.edge_indices[vertex.name] = len(self.edge_indices)\n",
|
||||
" return True\n",
|
||||
" else:\n",
|
||||
" return False\n",
|
||||
" \n",
|
||||
" def add_edge(self, u, v, weight=1):\n",
|
||||
" if u in self.vertices and v in self.vertices:\n",
|
||||
" self.edges[self.edge_indices[u]][self.edge_indices[v]] = weight\n",
|
||||
" self.edges[self.edge_indices[v]][self.edge_indices[u]] = weight\n",
|
||||
" return True\n",
|
||||
" else:\n",
|
||||
" return False\n",
|
||||
" \n",
|
||||
" def print_graph(self):\n",
|
||||
" for v, i in sorted(self.edge_indices.items()):\n",
|
||||
" print(v + ' ', end='')\n",
|
||||
" for j in range(len(self.edges)):\n",
|
||||
" print(self.edges[i][j], end=' ')\n",
|
||||
" print(' ')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Test Code\n",
|
||||
"Here we create a new Graph object. We create a new vertex named A. We add A to the graph. Then we add new vertex B to the graph. Then we iterate from A to K and add a bunch of vertices to the graph. Since the add_vertex method checks for duplicates, A and B are not added twice.\n",
|
||||
"This is exactly the same test code we used for the graph with adjacency lists."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"g = Graph()\n",
|
||||
"a = Vertex('A')\n",
|
||||
"g.add_vertex(a)\n",
|
||||
"g.add_vertex(Vertex('B'))\n",
|
||||
"for i in range(ord('A'), ord('K')):\n",
|
||||
" g.add_vertex(Vertex(chr(i)))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"An edge consists of two vertex names. Here we iterate through a list of edges and add each to the graph. \n",
|
||||
"\n",
|
||||
"This print_graph method doesn't give a very good visualization of the graph, but it does show the adjacency matrix so we can see each vertex's neighbors."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"A 0 1 0 0 1 0 0 0 0 0 \n",
|
||||
"B 1 0 0 0 0 1 0 0 0 0 \n",
|
||||
"C 0 0 0 0 0 0 1 0 0 0 \n",
|
||||
"D 0 0 0 0 1 0 0 1 0 0 \n",
|
||||
"E 1 0 0 1 0 0 0 1 0 0 \n",
|
||||
"F 0 1 0 0 0 0 1 0 1 1 \n",
|
||||
"G 0 0 1 0 0 1 0 0 0 1 \n",
|
||||
"H 0 0 0 1 1 0 0 0 1 0 \n",
|
||||
"I 0 0 0 0 0 1 0 1 0 0 \n",
|
||||
"J 0 0 0 0 0 1 1 0 0 0 \n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"edges = ['AB', 'AE', 'BF', 'CG', 'DE', 'DH', 'EH', 'FG', 'FI', 'FJ', 'GJ', 'HI']\n",
|
||||
"for edge in edges:\n",
|
||||
" g.add_edge(edge[0], edge[1])\n",
|
||||
"\n",
|
||||
"g.print_graph()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"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
|
||||
}
|
||||
BIN
Section_5/Graphs.pdf
Normal file
BIN
Section_5/Graphs.pdf
Normal file
Binary file not shown.
47
Section_5/graph_adjacency-list.py
Normal file
47
Section_5/graph_adjacency-list.py
Normal file
@@ -0,0 +1,47 @@
|
||||
# implementation of an undirected graph using Adjacency Lists
|
||||
class Vertex:
|
||||
def __init__(self, n):
|
||||
self.name = n
|
||||
self.neighbors = list()
|
||||
|
||||
def add_neighbor(self, v):
|
||||
if v not in self.neighbors:
|
||||
self.neighbors.append(v)
|
||||
self.neighbors.sort()
|
||||
|
||||
class Graph:
|
||||
vertices = {}
|
||||
|
||||
def add_vertex(self, vertex):
|
||||
if isinstance(vertex, Vertex) and vertex.name not in self.vertices:
|
||||
self.vertices[vertex.name] = vertex
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def add_edge(self, u, v):
|
||||
if u in self.vertices and v in self.vertices:
|
||||
# my YouTube video shows a silly for loop here, but this is a much faster way to do it
|
||||
self.vertices[u].add_neighbor(v)
|
||||
self.vertices[v].add_neighbor(u)
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def print_graph(self):
|
||||
for key in sorted(list(self.vertices.keys())):
|
||||
print(key + str(self.vertices[key].neighbors))
|
||||
|
||||
g = Graph()
|
||||
# print(str(len(g.vertices)))
|
||||
a = Vertex('A')
|
||||
g.add_vertex(a)
|
||||
g.add_vertex(Vertex('B'))
|
||||
for i in range(ord('A'), ord('K')):
|
||||
g.add_vertex(Vertex(chr(i)))
|
||||
|
||||
edges = ['AB', 'AE', 'BF', 'CG', 'DE', 'DH', 'EH', 'FG', 'FI', 'FJ', 'GJ', 'HI']
|
||||
for edge in edges:
|
||||
g.add_edge(edge[:1], edge[1:])
|
||||
|
||||
g.print_graph()
|
||||
49
Section_5/graph_adjacency-matrix.py
Normal file
49
Section_5/graph_adjacency-matrix.py
Normal file
@@ -0,0 +1,49 @@
|
||||
# implementation of an undirected graph using Adjacency Matrix, with weighted or unweighted edges
|
||||
class Vertex:
|
||||
def __init__(self, n):
|
||||
self.name = n
|
||||
|
||||
class Graph:
|
||||
vertices = {}
|
||||
edges = []
|
||||
edge_indices = {}
|
||||
|
||||
def add_vertex(self, vertex):
|
||||
if isinstance(vertex, Vertex) and vertex.name not in self.vertices:
|
||||
self.vertices[vertex.name] = vertex
|
||||
for row in self.edges:
|
||||
row.append(0)
|
||||
self.edges.append([0] * (len(self.edges)+1))
|
||||
self.edge_indices[vertex.name] = len(self.edge_indices)
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def add_edge(self, u, v, weight=1):
|
||||
if u in self.vertices and v in self.vertices:
|
||||
self.edges[self.edge_indices[u]][self.edge_indices[v]] = weight
|
||||
self.edges[self.edge_indices[v]][self.edge_indices[u]] = weight
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def print_graph(self):
|
||||
for v, i in sorted(self.edge_indices.items()):
|
||||
print(v + ' ', end='')
|
||||
for j in range(len(self.edges)):
|
||||
print(self.edges[i][j], end='')
|
||||
print(' ')
|
||||
|
||||
g = Graph()
|
||||
# print(str(len(g.vertices)))
|
||||
a = Vertex('A')
|
||||
g.add_vertex(a)
|
||||
g.add_vertex(Vertex('B'))
|
||||
for i in range(ord('A'), ord('K')):
|
||||
g.add_vertex(Vertex(chr(i)))
|
||||
|
||||
edges = ['AB', 'AE', 'BF', 'CG', 'DE', 'DH', 'EH', 'FG', 'FI', 'FJ', 'GJ', 'HI']
|
||||
for edge in edges:
|
||||
g.add_edge(edge[:1], edge[1:])
|
||||
|
||||
g.print_graph()
|
||||
Reference in New Issue
Block a user