diff --git a/DIRECTORY.md b/DIRECTORY.md index 5cf3c38..36917de 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -14,3 +14,9 @@ * [recursive_bubble_sort](/sorts/recursive_bubble_sort.f90) * [merge_sort](/sorts/merge_sort.f90) * [example_usage_merge_sort](/sorts/example_usage_merge_sort.f90) +* [heap_sort](/sorts/heap_sort.f90) +* [example_usage_heap_sort](/sorts/example_usage_heap_sort.f90) +* [tests_heap_sort](/sorts/tests_heap_sort.f90) +* [gnome_sort](/sorts/gnome_sort.f90) +* [example_usage_gnome_sort](/sorts/example_usage_gnome_sort.f90) +* [tests_gnome_sort](/sorts/tests_gnome_sort.f90) diff --git a/sorts/example_usage_gnome_sort.f90 b/sorts/example_usage_gnome_sort.f90 new file mode 100644 index 0000000..d9cd0c4 --- /dev/null +++ b/sorts/example_usage_gnome_sort.f90 @@ -0,0 +1,22 @@ +!> Test program for the Gnome Sort algorithm + +!! This program demonstrates the use of the gnome_sort_module by sorting an array of integers. + +program test_gnome_sort + use gnome_sort_module + implicit none + integer, dimension(10) :: array ! Test array + integer :: n, i + + ! Initialize the test array + array = (/ -5, 2, 9, 1, 5, 6, -7, 8, 15, -20 /) + n = size(array) + + ! Call gnome_sort from the module to sort the array + call gnome_sort(array) + + print *, "Sorted array:" + do i = 1, n + print *, array(i) + end do +end program test_gnome_sort diff --git a/sorts/example_usage_heap_sort.f90 b/sorts/example_usage_heap_sort.f90 new file mode 100644 index 0000000..a394dcc --- /dev/null +++ b/sorts/example_usage_heap_sort.f90 @@ -0,0 +1,31 @@ +!> Example program for the Heap Sort algorithm +!! +!! This program demonstrates the use of the heap_sort_module by sorting an array of integers. + +program test_heap_sort + use heap_sort_module + implicit none + integer, parameter :: n = 12 + integer :: i + integer, dimension(n) :: array(n) ! Test array + + ! Initialize the test array + array = (/ 12, 11, 13, 5, 6, 7, 3, 9, -1, 2, -12, 1 /) + n = size(array) + + ! Print the original array + print *, "Original array:" + do i = 1, n + print *, array(i) + end do + + ! Call heap_sort from the module to sort the array + call heap_sort(array, n) + + ! Print the sorted array + print *, "Sorted array:" + do i = 1, n + print *, array(i) + end do + +end program test_heap_sort diff --git a/sorts/gnome_sort.f90 b/sorts/gnome_sort.f90 new file mode 100644 index 0000000..b92e912 --- /dev/null +++ b/sorts/gnome_sort.f90 @@ -0,0 +1,54 @@ +!> Gnome Sort Algorithm + +!> This module implements the Gnome Sort algorithm. +!! +!! Gnome Sort is a simple comparison-based sorting algorithm. +!! It iterates through the array, comparing and swapping elements if needed. +!! +!! Time Complexity: O(n^2) where n is the number of elements in the input array. +!! +!! Input: +!! - An array of integers. +!! +!! Output: +!! - A sorted array of integers. +module gnome_sort_module + implicit none + +contains + + !> Subroutine to sort an array using Gnome Sort + subroutine gnome_sort(array) + implicit none + integer, dimension(:), intent(inout) :: array ! Input/output array to be sorted + integer :: i, n + + n = size(array) + i = 1 + + ! Gnome Sort algorithm + do while (i <= n) + if (i == 1 .or. array(i) >= array(i - 1)) then + i = i + 1 + else + ! Swap elements + call swap(array(i), array(i - 1)) + i = i - 1 + end if + end do + + end subroutine gnome_sort + + !> Helper subroutine to swap two elements in an array + subroutine swap(x, y) + implicit none + integer, intent(inout) :: x, y + integer :: temp + + temp = x + x = y + y = temp + + end subroutine swap + +end module gnome_sort_module diff --git a/sorts/heap_sort.f90 b/sorts/heap_sort.f90 new file mode 100644 index 0000000..9ba1bf5 --- /dev/null +++ b/sorts/heap_sort.f90 @@ -0,0 +1,87 @@ +!> ## Heap Sort Algorithm +!> +!! This module implements the Heap Sort algorithm. +!! +!! Heap Sort is a comparison-based sorting algorithm that uses a binary heap data structure. +!! It first builds a max heap from the input data and then repeatedly extracts the maximum +!! element from the heap and reconstructs the heap until the array is sorted. +!! +!! Time Complexity: O(n log n) where n is the number of elements in the input array. +!! +!! Input: +!! - An array of integers. +!! +!! Output: +!! - A sorted array of integers. +module heap_sort_module + implicit none + +contains + + !> Subroutine to perform heap sort on an array + subroutine heap_sort(array, n) + implicit none + integer, dimension(:), intent(inout) :: array ! Input/output array to be sorted + integer, intent(in) :: n ! Size of the array + integer :: i + + ! Build the max heap + do i = n / 2, 1, -1 + call heapify(array, n, i) + end do + + ! Extract elements one by one from the heap + do i = n, 2, -1 + ! Move the current root to the end + call swap(array, 1, i) + + ! Call max heapify on the reduced heap + call heapify(array, i - 1, 1) + end do + + end subroutine heap_sort + + !> Subroutine to maintain the heap property + recursive subroutine heapify(array, n, i) + implicit none + integer, dimension(:), intent(inout) :: array ! Input/output array to be heapified + integer, intent(in) :: n ! Size of the heap + integer, intent(in) :: i ! Index of the root + integer :: largest, left, right + + largest = i + left = 2 * i + right = 2 * i + 1 + + ! Is Left Child is larger than Root? + if (left <= n .and. array(left) > array(largest)) then + largest = left + end if + + ! Is Right Child larger than Largest so far? + if (right <= n .and. array(right) > array(largest)) then + largest = right + end if + + ! Swap and heapify if Root is not the Largest + if (largest /= i) then + call swap(array, i, largest) + call heapify(array, n, largest) + end if + + end subroutine heapify + + !> Subroutine helper to swap two elements in an array + subroutine swap(array, i, j) + implicit none + integer, dimension(:), intent(inout) :: array ! Input/output array in which elements are swapped + integer, intent(in) :: i, j ! Indices of the elements to be swapped + integer :: temp + + temp = array(i) + array(i) = array(j) + array(j) = temp + + end subroutine swap + +end module heap_sort_module \ No newline at end of file diff --git a/sorts/tests_gnome_sort.f90 b/sorts/tests_gnome_sort.f90 new file mode 100644 index 0000000..1e2bdae --- /dev/null +++ b/sorts/tests_gnome_sort.f90 @@ -0,0 +1,93 @@ +!> Test program for the Gnome Sort algorithm + +!! This program provides additional test cases to validate the gnome_sort_module. + +program tests_gnome_sort + + use gnome_sort_module + implicit none + integer :: i + integer, dimension(:), allocatable :: array + + ! Test 1: Repeated elements + print *, "Test 1: Array with repeated elements" + array = (/ 5, 3, 8, 3, 1, 5, 7, 5, 10, 7, 3, 1 /) + call run_test(array) + + ! Test 2: Already sorted array + print *, "Test 2: Already sorted array" + if (allocated(array)) deallocate(array) + allocate(array(8)) + array = (/ 1, 2, 3, 4, 5, 6, 7, 8 /) + call run_test(array) + + ! Test 3: Reverse sorted array + print *, "Test 3: Reverse sorted array" + if (allocated(array)) deallocate(array) + allocate(array(8)) + array = (/ 8, 7, 6, 5, 4, 3, 2, 1 /) + call run_test(array) + + ! Test 4: Array with all negative numbers + print *, "Test 4: Array with all negative numbers" + if (allocated(array)) deallocate(array) + allocate(array(8)) + array = (/ -1, -5, -3, -7, -2, -12, -15, -4 /) + call run_test(array) + + ! Test 5: Single element array + print *, "Test 5: Single element array" + if (allocated(array)) deallocate(array) + allocate(array(1)) + array = (/ 42 /) + call run_test(array) + + ! Test 6: Array with identical elements + print *, "Test 6: Array with identical elements" + if (allocated(array)) deallocate(array) + allocate(array(5)) + array = (/ 7, 7, 7, 7, 7 /) + call run_test(array) + + ! Test 7: Array with alternating high and low values + print *, "Test 7: Array with alternating high and low values" + if (allocated(array)) deallocate(array) + allocate(array(6)) + array = (/ 1, 1000, 2, 999, 3, 998 /) + call run_test(array) + + ! Test 8: Empty array + print *, "Test 8: Empty array" + if (allocated(array)) deallocate(array) + allocate(array(0)) + call run_test(array) + +contains + + !> Subroutine to run and print the gnome sort test + subroutine run_test(array) + integer, dimension(:), intent(inout) :: array + integer :: n, i + + n = size(array) + + ! Print original array + print *, "Original array:" + do i = 1, n + print *, array(i) + end do + + ! Call gnome_sort + call gnome_sort(array) + + ! Print sorted array + print *, "Sorted array:" + do i = 1, n + print *, array(i) + end do + + print *, "" + end subroutine run_test + + +end program tests_gnome_sort \ No newline at end of file diff --git a/sorts/tests_heap_sort.f90 b/sorts/tests_heap_sort.f90 new file mode 100644 index 0000000..1961d80 --- /dev/null +++ b/sorts/tests_heap_sort.f90 @@ -0,0 +1,93 @@ +!> Test program for the Heap Sort algorithm + +!! This program provides additional test cases to validate the heap_sort_module. + +program tests_heap_sort + + use heap_sort_module + implicit none + integer :: i + integer, dimension(:), allocatable :: array + + ! Test 1: Repeated elements + print *, "Test 1: Array with repeated elements" + array = (/ 5, 3, 8, 3, 1, 5, 7, 5, 10, 7, 3, 1 /) + call run_test(array) + + ! Test 2: Already sorted array + print *, "Test 2: Already sorted array" + if (allocated(array)) deallocate(array) + allocate(array(8)) + array = (/ 1, 2, 3, 4, 5, 6, 7, 8 /) + call run_test(array) + + ! Test 3: Reverse sorted array + print *, "Test 3: Reverse sorted array" + if (allocated(array)) deallocate(array) + allocate(array(8)) + array = (/ 8, 7, 6, 5, 4, 3, 2, 1 /) + call run_test(array) + + ! Test 4: Array with all negative numbers + print *, "Test 4: Array with all negative numbers" + if (allocated(array)) deallocate(array) + allocate(array(8)) + array = (/ -1, -5, -3, -7, -2, -12, -15, -4 /) + call run_test(array) + + ! Test 5: Single element array + print *, "Test 5: Single element array" + if (allocated(array)) deallocate(array) + allocate(array(1)) + array = (/ 42 /) + call run_test(array) + + ! Test 6: Array with identical elements + print *, "Test 6: Array with identical elements" + if (allocated(array)) deallocate(array) + allocate(array(5)) + array = (/ 7, 7, 7, 7, 7 /) + call run_test(array) + + ! Test 7: Array with alternating high and low values + print *, "Test 7: Array with alternating high and low values" + if (allocated(array)) deallocate(array) + allocate(array(6)) + array = (/ 1, 1000, 2, 999, 3, 998 /) + call run_test(array) + + ! Test 8: Empty array + print *, "Test 8: Empty array" + if (allocated(array)) deallocate(array) + allocate(array(0)) + call run_test(array) + +contains + + !> Subroutine to run and print the heap sort test + subroutine run_test(array) + integer, dimension(:), intent(inout) :: array + integer :: n, i + + n = size(array) + + ! Print original array + print *, "Original array:" + do i = 1, n + print *, array(i) + end do + + ! Call heap_sort + call heap_sort(array, n) + + ! Print sorted array + print *, "Sorted array:" + do i = 1, n + print *, array(i) + end do + + print *, "" + end subroutine run_test + + +end program tests_heap_sort \ No newline at end of file