Adding algorithms and datastructures
This commit is contained in:
0
tests/__init__.py
Normal file
0
tests/__init__.py
Normal file
277
tests/test_data_structures.py
Normal file
277
tests/test_data_structures.py
Normal 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
|
||||
|
||||
100
tests/test_deterministic_algorithm.py
Normal file
100
tests/test_deterministic_algorithm.py
Normal 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([])
|
||||
|
||||
107
tests/test_randomized_algorithm.py
Normal file
107
tests/test_randomized_algorithm.py
Normal 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([])
|
||||
|
||||
Reference in New Issue
Block a user