DSAN 5500: Data Structures, Objects, and Algorithms in Python
Monday, February 12, 2024
from hw2 import LinkedList, InventoryItem
ll = LinkedList()
item1 = InventoryItem('Mango', 50)
ll.append(item1)
item2 = InventoryItem('Pickle', 60)
ll.append(item2)
item3 = InventoryItem('Artichoke', 55)
ll.append(item3)
item5 = InventoryItem('Banana', 123)
ll.append(item5)
item6 = InventoryItem('Aardvark', 11)
ll.append(item6)
HTML(visualize_ll(ll))
from hw2 import BinarySearchTree
bst = BinarySearchTree()
item1 = InventoryItem('Mango', 50)
bst.add(item1)
item2 = InventoryItem('Pickle', 60)
bst.add(item2)
item3 = InventoryItem('Artichoke', 55)
bst.add(item3)
item5 = InventoryItem('Banana', 123)
bst.add(item5)
item6 = InventoryItem('Aardvark', 11)
bst.add(item6)
HTML(visualize(bst))
collections.abc.Hashable
class, such that hash(my_obj)
works iff isinstance(my_obj, Hashable)
int
, str
, datetime
) come with implementations of ordering, but if you make your own class you need to implement the ordering for it!==
, <
, >=
“Just Work”obj1 < obj2
class UtilVector:
def __init__(self, u1, u2):
self.u1 = u1
self.u2 = u2
def __eq__(self, other):
if not isinstance(other, UtilVector):
return NotImplemented
return self.u1 == other.u1 and self.u2 == other.u2
def __ne__(self, other):
if not isinstance(other, UtilVector):
return NotImplemented
return self.u1 != other.u1 or self.u2 != other.u2
def __gt__(self, other):
if not isinstance(other, UtilVector):
return NotImplemented
return self.u1 > other.u1 and self.u2 >= other.u2 or self.u1 >= other.u1 and self.u2 > other.u2
def __ge__(self, other):
return self.__gt__(other) or self.__eq__(other)
def __lt__(self, other):
if not isinstance(other, UtilVector):
return NotImplemented
return other.__gt__(self)
def __le__(self, other):
return self.__lt__(other) or self.__eq__(other)
xA = UtilVector(2, 2)
xB = UtilVector(3, 2)
print(xB > xA)
xC = UtilVector(2, 3)
print(xC > xB)
import itertools
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
x0 = UtilVector(4, 6)
util_vals = np.arange(0, 11, 0.5)
util_pairs = list(itertools.product(util_vals, util_vals))
util_df = pd.DataFrame(util_pairs, columns=['x','y'])
def compare_to_x0(row):
row_vec = UtilVector(row['x'], row['y'])
gt_result = int(row_vec > x0)
lt_result = int(row_vec < x0)
return gt_result - lt_result
util_df['greater'] = util_df.apply(compare_to_x0, axis=1)
#my_palette = sns.color_palette(['#E69F00','lightgray','#CCFFCC'])
my_palette = sns.color_palette(['#FF3535','lightgray','#35FF35'])
sns.relplot(
data=util_df,
x='x', y='y',
hue='greater',
palette=my_palette,
marker='X', s=150
);
x0_df = pd.DataFrame({'x': [4], 'y': [6]})
plt.scatter(data=x0_df, x='x', y='y', color='black')
plt.gca().set_aspect('equal')
True
False
InventoryItem
classitem_name
and price
__eq__(other)
, __ne__(other)
__lt__(other)
, __le__(other)
, __gt__(other)
, __ge__(other)
__repr__()
and __str__()
Depth-First Search (DFS)
Breadth-First Search (BFS)
DFS:
InventoryItem[item_name=Mango,price=50]
InventoryItem[item_name=Pickle,price=60]
InventoryItem[item_name=Artichoke,price=55]
InventoryItem[item_name=Banana,price=123]
InventoryItem[item_name=Aardvark,price=11]
BFS:
InventoryItem[item_name=Mango,price=50]
InventoryItem[item_name=Artichoke,price=55]
InventoryItem[item_name=Pickle,price=60]
InventoryItem[item_name=Aardvark,price=11]
InventoryItem[item_name=Banana,price=123]
NodeProcessor
, with a single iterate_over(tree)
functionThingContainer
(could be a stack or a queue, you won’t know which), which has two functions:
put_new_thing_in(new_thing)
take_existing_thing_out()
DFS Procedure | Algorithm |
---|---|
Pre-Order Traversal | 1. Print node 2. Traverse left subtree 3. Traverse right subtree |
In-Order Traversal 🧐‼️ | 1. Traverse left subtree 2. Print node 3. Traverse right subtree |
Post-Order Traversal | 1. Traverse left subtree 2. Traverse right subtree 3. Print node |
h('AA') = 0
, h('AB') = 1
, …, h('AZ') = 25
,h('BA') = 26
, h('BB') = 27
, …, h('BZ') = 51
,h('CA') = 52
, …, h('ZZ') = 675
.DSAN 5500 Week 5: Binary Search Trees