Adding algorithms and datastructures

This commit is contained in:
Carlos Gutierrez
2025-11-23 15:59:23 -05:00
commit d1d3423e99
21 changed files with 2653 additions and 0 deletions

0
tests/__init__.py Normal file
View File

View File

@@ -0,0 +1,277 @@
"""
Unit tests for elementary data structures.
Author: Carlos Gutierrez
Course: MSCS532 - Data Structures and Algorithms
"""
import pytest
from src.data_structures import (
DynamicArray, Matrix, Stack, Queue, LinkedList, Tree, TreeNode
)
class TestDynamicArray:
"""Test cases for DynamicArray."""
def test_initialization(self):
"""Test array initialization."""
arr = DynamicArray()
assert len(arr) == 0
def test_append(self):
"""Test append operation."""
arr = DynamicArray()
arr.append(1)
arr.append(2)
assert len(arr) == 2
assert arr[0] == 1
assert arr[1] == 2
def test_insert(self):
"""Test insert operation."""
arr = DynamicArray()
arr.append(1)
arr.append(3)
arr.insert(1, 2)
assert arr[1] == 2
assert len(arr) == 3
def test_delete(self):
"""Test delete operation."""
arr = DynamicArray()
arr.append(1)
arr.append(2)
arr.append(3)
value = arr.delete(1)
assert value == 2
assert len(arr) == 2
assert arr[1] == 3
def test_search(self):
"""Test search operation."""
arr = DynamicArray()
arr.append(1)
arr.append(2)
arr.append(3)
assert arr.search(2) == 1
assert arr.search(4) == -1
def test_index_error(self):
"""Test index error handling."""
arr = DynamicArray()
with pytest.raises(IndexError):
_ = arr[0]
arr.append(1)
with pytest.raises(IndexError):
_ = arr[1]
class TestMatrix:
"""Test cases for Matrix."""
def test_initialization(self):
"""Test matrix initialization."""
matrix = Matrix(3, 4)
assert matrix.rows == 3
assert matrix.cols == 4
def test_get_set(self):
"""Test get and set operations."""
matrix = Matrix(2, 2)
matrix[0, 0] = 1
matrix[0, 1] = 2
matrix[1, 0] = 3
matrix[1, 1] = 4
assert matrix[0, 0] == 1
assert matrix[1, 1] == 4
def test_index_error(self):
"""Test index error handling."""
matrix = Matrix(2, 2)
with pytest.raises(IndexError):
_ = matrix[3, 0]
class TestStack:
"""Test cases for Stack."""
def test_push_pop(self):
"""Test push and pop operations."""
stack = Stack()
stack.push(1)
stack.push(2)
assert stack.pop() == 2
assert stack.pop() == 1
def test_peek(self):
"""Test peek operation."""
stack = Stack()
stack.push(1)
stack.push(2)
assert stack.peek() == 2
assert stack.size() == 2
def test_is_empty(self):
"""Test is_empty operation."""
stack = Stack()
assert stack.is_empty()
stack.push(1)
assert not stack.is_empty()
def test_empty_pop(self):
"""Test pop from empty stack."""
stack = Stack()
with pytest.raises(IndexError):
stack.pop()
class TestQueue:
"""Test cases for Queue."""
def test_enqueue_dequeue(self):
"""Test enqueue and dequeue operations."""
queue = Queue()
queue.enqueue(1)
queue.enqueue(2)
assert queue.dequeue() == 1
assert queue.dequeue() == 2
def test_peek(self):
"""Test peek operation."""
queue = Queue()
queue.enqueue(1)
queue.enqueue(2)
assert queue.peek() == 1
assert queue.size() == 2
def test_is_empty(self):
"""Test is_empty operation."""
queue = Queue()
assert queue.is_empty()
queue.enqueue(1)
assert not queue.is_empty()
def test_empty_dequeue(self):
"""Test dequeue from empty queue."""
queue = Queue()
with pytest.raises(IndexError):
queue.dequeue()
class TestLinkedList:
"""Test cases for LinkedList."""
def test_append(self):
"""Test append operation."""
ll = LinkedList()
ll.append(1)
ll.append(2)
assert len(ll) == 2
assert ll.get(0) == 1
assert ll.get(1) == 2
def test_prepend(self):
"""Test prepend operation."""
ll = LinkedList()
ll.prepend(1)
ll.prepend(2)
assert ll.get(0) == 2
assert ll.get(1) == 1
def test_insert(self):
"""Test insert operation."""
ll = LinkedList()
ll.append(1)
ll.append(3)
ll.insert(1, 2)
assert ll.get(1) == 2
assert len(ll) == 3
def test_delete(self):
"""Test delete operation."""
ll = LinkedList()
ll.append(1)
ll.append(2)
ll.append(3)
value = ll.delete(1)
assert value == 2
assert len(ll) == 2
assert ll.get(1) == 3
def test_search(self):
"""Test search operation."""
ll = LinkedList()
ll.append(1)
ll.append(2)
ll.append(3)
assert ll.search(2) == 1
assert ll.search(4) == -1
def test_index_error(self):
"""Test index error handling."""
ll = LinkedList()
with pytest.raises(IndexError):
ll.get(0)
ll.append(1)
with pytest.raises(IndexError):
ll.get(1)
class TestTree:
"""Test cases for Tree."""
def test_initialization(self):
"""Test tree initialization."""
tree = Tree(1)
assert tree.root is not None
assert tree.root.value == 1
def test_insert(self):
"""Test insert operation."""
tree = Tree(1)
assert tree.insert(1, 2)
assert tree.insert(1, 3)
assert len(tree.root.children) == 2
def test_search(self):
"""Test search operation."""
tree = Tree(1)
tree.insert(1, 2)
tree.insert(2, 3)
assert tree.search(1)
assert tree.search(2)
assert tree.search(3)
assert not tree.search(4)
def test_delete(self):
"""Test delete operation."""
tree = Tree(1)
tree.insert(1, 2)
tree.insert(1, 3)
assert tree.delete(2)
assert not tree.search(2)
assert tree.search(3)
def test_traversal(self):
"""Test tree traversal."""
tree = Tree(1)
tree.insert(1, 2)
tree.insert(1, 3)
tree.insert(2, 4)
preorder = tree.traverse_preorder()
assert preorder == [1, 2, 4, 3]
postorder = tree.traverse_postorder()
assert postorder == [4, 2, 3, 1]
def test_height(self):
"""Test height calculation."""
tree = Tree(1)
assert tree.height() == 0
tree.insert(1, 2)
assert tree.height() == 1
tree.insert(2, 3)
assert tree.height() == 2

View File

@@ -0,0 +1,100 @@
"""
Unit tests for deterministic selection algorithm.
Author: Carlos Gutierrez
Course: MSCS532 - Data Structures and Algorithms
"""
import pytest
from src.deterministic_algorithm import deterministic_select, find_median
class TestDeterministicSelect:
"""Test cases for deterministic_select function."""
def test_basic_selection(self):
"""Test basic selection operations."""
arr = [3, 1, 4, 1, 5, 9, 2, 6]
assert deterministic_select(arr, 1) == 1
assert deterministic_select(arr, 2) == 1
assert deterministic_select(arr, 3) == 2
assert deterministic_select(arr, 4) == 3
assert deterministic_select(arr, len(arr)) == 9
def test_sorted_array(self):
"""Test on sorted array."""
arr = list(range(1, 11))
for i in range(1, 11):
assert deterministic_select(arr, i) == i
def test_reverse_sorted_array(self):
"""Test on reverse-sorted array."""
arr = list(range(10, 0, -1))
for i in range(1, 11):
assert deterministic_select(arr, i) == i
def test_duplicate_elements(self):
"""Test with duplicate elements."""
arr = [5, 5, 5, 3, 3, 1, 1, 1]
assert deterministic_select(arr, 1) == 1
assert deterministic_select(arr, 2) == 1
assert deterministic_select(arr, 3) == 1
assert deterministic_select(arr, 4) == 3
assert deterministic_select(arr, 5) == 3
assert deterministic_select(arr, 6) == 5
def test_single_element(self):
"""Test with single element."""
arr = [42]
assert deterministic_select(arr, 1) == 42
def test_empty_array(self):
"""Test with empty array."""
with pytest.raises(IndexError):
deterministic_select([], 1)
def test_invalid_k(self):
"""Test with invalid k values."""
arr = [1, 2, 3]
with pytest.raises(ValueError):
deterministic_select(arr, 0)
with pytest.raises(ValueError):
deterministic_select(arr, 4)
def test_key_function(self):
"""Test with custom key function."""
arr = [{'value': 3}, {'value': 1}, {'value': 2}]
result = deterministic_select(arr, 2, key=lambda x: x['value'])
assert result['value'] == 2
def test_large_array(self):
"""Test with larger array."""
arr = list(range(100, 0, -1))
assert deterministic_select(arr, 50) == 50
assert deterministic_select(arr, 1) == 1
assert deterministic_select(arr, 100) == 100
class TestFindMedian:
"""Test cases for find_median function."""
def test_odd_length(self):
"""Test median of odd-length array."""
arr = [3, 1, 4, 1, 5]
assert find_median(arr) == 3
def test_even_length(self):
"""Test median of even-length array (returns lower median)."""
arr = [3, 1, 4, 1, 5, 9]
assert find_median(arr) == 3
def test_sorted_array(self):
"""Test median of sorted array."""
arr = list(range(1, 11))
assert find_median(arr) == 5
def test_empty_array(self):
"""Test median of empty array."""
with pytest.raises(ValueError):
find_median([])

View File

@@ -0,0 +1,107 @@
"""
Unit tests for randomized selection algorithm.
Author: Carlos Gutierrez
Course: MSCS532 - Data Structures and Algorithms
"""
import pytest
from src.randomized_algorithm import randomized_select, find_median
class TestRandomizedSelect:
"""Test cases for randomized_select function."""
def test_basic_selection(self):
"""Test basic selection operations."""
arr = [3, 1, 4, 1, 5, 9, 2, 6]
assert randomized_select(arr, 1, seed=42) == 1
assert randomized_select(arr, 2, seed=42) == 1
assert randomized_select(arr, 3, seed=42) == 2
assert randomized_select(arr, 4, seed=42) == 3
assert randomized_select(arr, len(arr), seed=42) == 9
def test_sorted_array(self):
"""Test on sorted array."""
arr = list(range(1, 11))
for i in range(1, 11):
assert randomized_select(arr, i, seed=42) == i
def test_reverse_sorted_array(self):
"""Test on reverse-sorted array."""
arr = list(range(10, 0, -1))
for i in range(1, 11):
assert randomized_select(arr, i, seed=42) == i
def test_duplicate_elements(self):
"""Test with duplicate elements."""
arr = [5, 5, 5, 3, 3, 1, 1, 1]
assert randomized_select(arr, 1, seed=42) == 1
assert randomized_select(arr, 2, seed=42) == 1
assert randomized_select(arr, 3, seed=42) == 1
assert randomized_select(arr, 4, seed=42) == 3
assert randomized_select(arr, 5, seed=42) == 3
assert randomized_select(arr, 6, seed=42) == 5
def test_single_element(self):
"""Test with single element."""
arr = [42]
assert randomized_select(arr, 1, seed=42) == 42
def test_empty_array(self):
"""Test with empty array."""
with pytest.raises(IndexError):
randomized_select([], 1)
def test_invalid_k(self):
"""Test with invalid k values."""
arr = [1, 2, 3]
with pytest.raises(ValueError):
randomized_select(arr, 0)
with pytest.raises(ValueError):
randomized_select(arr, 4)
def test_key_function(self):
"""Test with custom key function."""
arr = [{'value': 3}, {'value': 1}, {'value': 2}]
result = randomized_select(arr, 2, key=lambda x: x['value'], seed=42)
assert result['value'] == 2
def test_large_array(self):
"""Test with larger array."""
arr = list(range(100, 0, -1))
assert randomized_select(arr, 50, seed=42) == 50
assert randomized_select(arr, 1, seed=42) == 1
assert randomized_select(arr, 100, seed=42) == 100
def test_reproducibility(self):
"""Test that results are reproducible with same seed."""
arr = [3, 1, 4, 1, 5, 9, 2, 6]
result1 = randomized_select(arr, 4, seed=42)
result2 = randomized_select(arr, 4, seed=42)
assert result1 == result2
class TestFindMedian:
"""Test cases for find_median function."""
def test_odd_length(self):
"""Test median of odd-length array."""
arr = [3, 1, 4, 1, 5]
assert find_median(arr, seed=42) == 3
def test_even_length(self):
"""Test median of even-length array (returns lower median)."""
arr = [3, 1, 4, 1, 5, 9]
assert find_median(arr, seed=42) == 3
def test_sorted_array(self):
"""Test median of sorted array."""
arr = list(range(1, 11))
assert find_median(arr, seed=42) == 5
def test_empty_array(self):
"""Test median of empty array."""
with pytest.raises(ValueError):
find_median([])