- Implemented complete Heapsort algorithm with max-heap operations - Implemented binary heap-based Priority Queue with all core operations - Created Task class for task scheduling applications - Implemented Task Scheduler simulation using priority queue - Added comprehensive test suite (70+ tests, all passing) - Implemented sorting algorithm comparison utilities (Heapsort vs Quicksort vs Merge Sort) - Added detailed README with comprehensive analysis and documentation - Included demonstration scripts for all features - Generated performance comparison plots - Modular, well-documented code following academic standards Author: Carlos Gutierrez Email: cgutierrez44833@ucumberlands.edu
157 lines
5.2 KiB
Python
157 lines
5.2 KiB
Python
"""
|
|
Test Suite for Heapsort Implementation
|
|
|
|
This module contains comprehensive tests for the heapsort algorithm,
|
|
including edge cases, different data types, and correctness verification.
|
|
|
|
Author: Carlos Gutierrez
|
|
Email: cgutierrez44833@ucumberlands.edu
|
|
"""
|
|
|
|
import unittest
|
|
import sys
|
|
import os
|
|
|
|
# Add parent directory to path to import src modules
|
|
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
|
|
|
|
from src.heapsort import heapsort, heap_extract_max, heap_insert, _build_max_heap, _heapify
|
|
|
|
|
|
class TestHeapsort(unittest.TestCase):
|
|
"""Test cases for heapsort function."""
|
|
|
|
def test_empty_array(self):
|
|
"""Test sorting an empty array."""
|
|
arr = []
|
|
result = heapsort(arr)
|
|
self.assertEqual(result, [])
|
|
|
|
def test_single_element(self):
|
|
"""Test sorting an array with a single element."""
|
|
arr = [42]
|
|
result = heapsort(arr)
|
|
self.assertEqual(result, [42])
|
|
|
|
def test_already_sorted(self):
|
|
"""Test sorting an already sorted array."""
|
|
arr = [1, 2, 3, 4, 5]
|
|
result = heapsort(arr)
|
|
self.assertEqual(result, [1, 2, 3, 4, 5])
|
|
|
|
def test_reverse_sorted(self):
|
|
"""Test sorting a reverse-sorted array."""
|
|
arr = [5, 4, 3, 2, 1]
|
|
result = heapsort(arr)
|
|
self.assertEqual(result, [1, 2, 3, 4, 5])
|
|
|
|
def test_random_array(self):
|
|
"""Test sorting a random array."""
|
|
arr = [12, 11, 13, 5, 6, 7]
|
|
result = heapsort(arr)
|
|
self.assertEqual(result, [5, 6, 7, 11, 12, 13])
|
|
|
|
def test_duplicate_elements(self):
|
|
"""Test sorting an array with duplicate elements."""
|
|
arr = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]
|
|
result = heapsort(arr)
|
|
self.assertEqual(result, [1, 1, 2, 3, 3, 4, 5, 5, 5, 6, 9])
|
|
|
|
def test_negative_numbers(self):
|
|
"""Test sorting an array with negative numbers."""
|
|
arr = [-5, -2, -8, 1, 3, -1]
|
|
result = heapsort(arr)
|
|
self.assertEqual(result, [-8, -5, -2, -1, 1, 3])
|
|
|
|
def test_large_array(self):
|
|
"""Test sorting a large array."""
|
|
arr = list(range(1000, 0, -1))
|
|
result = heapsort(arr)
|
|
self.assertEqual(result, list(range(1, 1001)))
|
|
|
|
def test_inplace_sorting(self):
|
|
"""Test that inplace sorting modifies the original array."""
|
|
arr = [3, 1, 4, 1, 5]
|
|
original_id = id(arr)
|
|
result = heapsort(arr, inplace=True)
|
|
self.assertEqual(id(result), original_id)
|
|
self.assertEqual(arr, [1, 1, 3, 4, 5])
|
|
|
|
def test_not_inplace_sorting(self):
|
|
"""Test that non-inplace sorting doesn't modify the original array."""
|
|
arr = [3, 1, 4, 1, 5]
|
|
original_arr = arr.copy()
|
|
result = heapsort(arr, inplace=False)
|
|
self.assertNotEqual(id(result), id(arr))
|
|
self.assertEqual(arr, original_arr)
|
|
self.assertEqual(result, [1, 1, 3, 4, 5])
|
|
|
|
def test_custom_key_function(self):
|
|
"""Test sorting with a custom key function."""
|
|
arr = [{'value': 3}, {'value': 1}, {'value': 4}]
|
|
result = heapsort(arr, key=lambda x: x['value'], inplace=False)
|
|
self.assertEqual([x['value'] for x in result], [1, 3, 4])
|
|
|
|
|
|
class TestHeapOperations(unittest.TestCase):
|
|
"""Test cases for heap utility functions."""
|
|
|
|
def test_heapify(self):
|
|
"""Test the heapify function."""
|
|
arr = [4, 10, 3, 5, 1]
|
|
_heapify(arr, 5, 0)
|
|
# After heapify, root should be the maximum
|
|
self.assertEqual(arr[0], 10)
|
|
|
|
def test_build_max_heap(self):
|
|
"""Test building a max-heap from an array."""
|
|
arr = [4, 10, 3, 5, 1]
|
|
_build_max_heap(arr)
|
|
# Root should be maximum
|
|
self.assertEqual(arr[0], 10)
|
|
# Verify heap property: parent >= children
|
|
for i in range(len(arr)):
|
|
left = 2 * i + 1
|
|
right = 2 * i + 2
|
|
if left < len(arr):
|
|
self.assertGreaterEqual(arr[i], arr[left])
|
|
if right < len(arr):
|
|
self.assertGreaterEqual(arr[i], arr[right])
|
|
|
|
def test_heap_extract_max(self):
|
|
"""Test extracting maximum from a heap."""
|
|
heap = [10, 5, 3, 4, 1]
|
|
_build_max_heap(heap)
|
|
max_val = heap_extract_max(heap)
|
|
self.assertEqual(max_val, 10)
|
|
self.assertEqual(len(heap), 4)
|
|
# Verify heap property is maintained
|
|
self.assertEqual(heap[0], 5)
|
|
|
|
def test_heap_extract_max_empty(self):
|
|
"""Test extracting from an empty heap raises error."""
|
|
heap = []
|
|
with self.assertRaises(IndexError):
|
|
heap_extract_max(heap)
|
|
|
|
def test_heap_insert(self):
|
|
"""Test inserting into a heap."""
|
|
heap = [10, 5, 3, 4, 1]
|
|
_build_max_heap(heap)
|
|
heap_insert(heap, 15)
|
|
# New maximum should be at root
|
|
self.assertEqual(heap[0], 15)
|
|
# Verify heap property
|
|
for i in range(len(heap)):
|
|
left = 2 * i + 1
|
|
right = 2 * i + 2
|
|
if left < len(heap):
|
|
self.assertGreaterEqual(heap[i], heap[left])
|
|
if right < len(heap):
|
|
self.assertGreaterEqual(heap[i], heap[right])
|
|
|
|
|
|
if __name__ == '__main__':
|
|
unittest.main()
|
|
|