0% found this document useful (0 votes)
11 views

DAA-Programming-Project_1

The document outlines a programming project for CS 111 focused on the empirical analysis of six sorting algorithms implemented in C. It details the program's functionality, including user input for array size and data generation, execution flow, and performance analysis through execution time measurements for various input sizes. The project aims to compare the efficiency of sorting algorithms such as Selection Sort, Bubble Sort, Insertion Sort, Mergesort, Quicksort, and Heapsort.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
11 views

DAA-Programming-Project_1

The document outlines a programming project for CS 111 focused on the empirical analysis of six sorting algorithms implemented in C. It details the program's functionality, including user input for array size and data generation, execution flow, and performance analysis through execution time measurements for various input sizes. The project aims to compare the efficiency of sorting algorithms such as Selection Sort, Bubble Sort, Insertion Sort, Mergesort, Quicksort, and Heapsort.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 26

CS 111: DESIGN AND ANALYSIS OF ALGORITHMS

A.Y. 2024 - 2025

PROGRAMMING PROJECT 1

EMPIRICAL ANALYSIS OF
SORTING ALGORITHMS

Project Members:

BS COMPUTER SCIENCE 2A
Cadag, Jaycee D.
Dela Cruz, Mark L.
Espinas, A Z Rain L.
Loviña, John Melrick M.
Morcozo, Janna Carla R.
PROGRAMMING PROJECT REPORT

I.​ DOCUMENTATION
A.​ Overview
Our program, written in C, implements six common sorting algorithms: Selection
Sort, Bubble Sort, Insertion Sort, Mergesort, Quicksort (with a median-of-three pivot
selection), and Heapsort, all operating on arrays of 32-bit integers to facilitate the
performance analysis of the sorting algorithms. The program allows the user to specify
the size of an integer array and choose between random or incrementally generated
data. It then sorts the array using each of the six algorithms, measures their execution
times, and outputs the original and sorted arrays, along with the execution times, to both
the console and a text file ("output.txt"). This program helps to compare the
performance of these algorithms under various input sizes and data distributions.

B.​ Program Specifications


​ Our program consists of the following key components:

Table 1. The key components of the program with their description or purpose

Description / Purpose in the


Key Components
Program
Header Files stdio.h Standard Input/Output: Provides functions
for standard input and output operations
used in the program, including printf(),
scanf(), fopen(), and fprintf().

stdlib.h Standard Library: Provides functions for


memory allocation (malloc()) and
deallocation (free()), random number
generation (rand(), srand()), and system
calls (system()).

string.h String Handling: Provides the strlen()


function to calculate string length.

time.h Time Functions: Provides the time() and


clock() function for measuring computation
time of sorting algorithms.

Constants MAX_RANGE A constant that defines the maximum


possible value (upper limit) for elements
within the array, used during the random
generation of array values.

Global cpu_time_used Stores the execution time of each sorting


Variables algorithm.

Main Function main() ●​ Displays a menu for sorting algorithm


selection.
●​ Gets user input for array size and data
generation method.
●​ Executes the selected sorting algorithm.
●​ Writes results to an output file.

Sorting selectionSort() Implements Selection Sort.


Algorithms bubbleSort() Implements Bubble Sort.

insertionSort() Implements Insertion Sort.

mergeSort(), merge(), Implements Mergesort.


performMergeSort()
merge(): Function to merge two sorted
subarrays into a single sorted array.

performMergeSort(): Recursive function to


implement Mergesort.

quickSort(), Implements Quicksort using the


medianOfThree(), median-of-three pivot selection.
partition(),
performQuickSort() medianOfThree(): Function to choose the
pivot using the median-of-three method.

partition(): Function to create partitions


for Quicksort.

performQuickSort(): Recursive function to


perform Quicksort using the median-of-three
method.

heapSort(), Implements Heapsort.


maxHeapify(),
buildMaxHeap(), maxHeapify(): Recursive function to
performHeapSort() max-heapify the input array.

buildMaxHeap(): Function to build a


max-heap from the given array.

performHeapSort(): Function to perform


heapsort.

Helper sizeArray() Returns the array size from user input.


Functions
copyArray() Creates a copy of the input array.

initArrayAndGet() Initializes the array based on the selected


data generation method.

arrayRandomGenerator() Fills the array with random values using the


rand() function in C.

arrayIncrementGenerator() Fills the array with an increasing sequence


of values.

swap() Swaps two elements in the array.


(Mainly used for Quicksort.)

printArray() Writes data to an output file.

printRuntime() Prints the execution time of sorting


algorithms.

Aesthetic load(), loadFast(() Simulates loading for program aesthetics.


Functions for
User Interface printCenter() Centers and prints text (i.e., title of the
(UI) program).

Furthermore, the program includes error handling for memory allocation and file
opening, validates user input, and prevents memory leaks by freeing all dynamically
allocated memory with free().
C.​ Execution Flow of the Program
​ The execution flow of the program involves user interaction for determining the
input size, generating, and then sorting the array, measuring the execution time, and
displaying the output, as detailed below:
1.​ The program begins by clearing the console, displaying the title, and prompting the
user to input the desired size (N) of the array. Once the array size is determined, the
program dynamically allocates memory for the array. If memory allocation fails, the
program outputs an error, and terminates.
2.​ After allocating memory for the array, the program requests the user to select a data
generation method (random or incremental).
(a)​If random generation is selected, the program proceeds to populate the array.
(b)​If incremental generation is selected, the program prompts the user for the
starting value.
3.​ The array is then populated according to the user's chosen data generation method.
4.​ The original array is then written to the output file (output.txt).
5.​ Subsequently, the program creates a copy of the original array for each sorting
algorithm to ensure the original data remains unchanged. The program then
executes and measures the execution time, using the clock() function, of each
sorting algorithm. The allocated memory for each copy is freed immediately after its
sorting operation.
6.​ The sorted array and measured execution time for each sorting algorithm is then
written to both the console and the output file.
7.​ Finally, the dynamically allocated memory for the original array is released, the
output file is closed, and the program terminates.

(a)​The images below show the program output in the terminal and output file for
random data generation.
(b)​The images below show the program output in the terminal and output file for
incremental data generation,
II.​ PROGRAM EXECUTION
A.​ Random Input Case
The program was executed multiple times for six distinct array sizes: N = 10, 100,
1000, 10000, 100000, and 1000000. For each value of N, the program was run five
separate times, with each run generating a unique random array.
The following images display the recorded execution times for each sorting
algorithm across the varied array sizes. Each image represents the running time for
every input size, from the five individual runs performed for each N value.

N = 10
N = 100

N = 1000
N = 10000
N = 100000

N = 1000000
B.​ Sorted Input Case
The program was executed multiple times for six distinct array sizes: N = 10, 100,
1000, 10000, 100000, and 1000000. For each value of N, the program was run five
separate times, with each run generating an incrementally sorted array.
The following images display the recorded execution times for each sorting
algorithm across the varied array sizes. Each image represents the running time for
every input size, from the five individual runs performed for each N value.​

N = 10

N = 100

N = 1000
N = 10000
N = 100000

N = 1000000






















III.​ EMPIRICAL ANALYSIS
A.​ Performance Analysis
1.​ Random Input Case

Table 2.1. Result of the experiment for random input, N = 10

Average
Sorting
Run 1 Run 2 Run 3 Run 4 Run 5 Time for
Algorithm
N = 10

Selection Sort 0.000002s 0.000002s 0.000002s 0.000001s 0.000002s 0.000002s

Bubble Sort 0.000001s 0.000001s 0.000001s 0.000001s 0.000001s 0.000001s

Insertion Sort 0.000001s 0.000002s 0.000002s 0.000001s 0.000001s 0.000001s

Mergesort 0.000003s 0.000002s 0.000002s 0.000002s 0.000002s 0.000002s

Quicksort 0.000002s 0.000002s 0.000002s 0.000002s 0.000002s 0.000002s

Heapsort 0.000001s 0.000001s 0.000001s 0.000001s 0.000001s 0.000001s

Table 2.2. Result of the experiment for random input, N = 100

Average
Sorting
Run 1 Run 2 Run 3 Run 4 Run 5 Time for
Algorithm
N = 100

Selection Sort 0.000020s 0.000020s 0.000023s 0.000024s 0.000023s 0.000024s

Bubble Sort 0.000025s 0.000021s 0.000021s 0.000021s 0.000032s 0.000024s

Insertion Sort 0.000013s 0.000012s 0.000015s 0.000014s 0.000014s 0.000014s

Mergesort 0.000015s 0.000014s 0.000009s 0.000015s 0.000008s 0.000012s

Quicksort 0.000007s 0.000009s 0.000011s 0.000007s 0.000007s 0.000008s

Heapsort 0.000009s 0.000008s 0.000015s 0.000009s 0.000008s 0.000010s

Table 2.3. Result of the experiment for random input, N = 1000

Average
Sorting
Run 1 Run 2 Run 3 Run 4 Run 5 Time for
Algorithm
N = 1000

Selection Sort 0.001160s 0.001875s 0.001533s 0.001553s 0.001575s 0.001539s

Bubble Sort 0.003005s 0.002897s 0.003659s 0.002917s 0.002911s 0.003078s

Insertion Sort 0.001021s 0.000986s 0.001021s 0.001006s 0.000980s 0.001003s

Mergesort 0.000095s 0.000105s 0.000102s 0.000112s 0.000112s 0.000105s

Quicksort 0.000081s 0.000083s 0.000079s 0.000080s 0.000085s 0.000082s

Heapsort 0.000113s 0.000108s 0.000117s 0.000138s 0.000148s 0.00012s


Table 2.4. Result of the experiment for random input, N = 10000

Average
Sorting
Run 1 Run 2 Run 3 Run 4 Run 5 Time for
Algorithm
N = 10000

Selection Sort 0.138315s 0.217852s 0.169093s 0.156381s 0.181280s 0.172584s

Bubble Sort 0.318491s 0.308807s 0.313877s 0.318411s 0.325277s 0.316973s

Insertion Sort 0.099821s 0.101790s 0.100970s 0.110240s 0.105385s 0.103641s

Merge Sort 0.001261s 0.001299s 0.001275s 0.001311s 0.001259s 0.001281s

Quick Sort 0.001082s 0.001051s 0.001046s 0.001050s 0.001059s 0.001058s

Heap Sort 0.001517s 0.001442s 0.001493s 0.001625s 0.001512s 0.001518s

Table 2.5. Result of the experiment for random input, N = 100000

Sorting Average
Run 1 Run 2 Run 3 Run 4 Run 5 Time for
Algorithm
N = 100000

16.138176 15.804050 16.515627 16.358828 16.136238


Selection Sort s
15.86451s
s s s s

44.082613 47.373826 48.031741 47.540115 48.050915 47.015842


Bubble Sort s s s s s s

10.685412 10.765457 10.765457 10.998133 11.045482 10.851988


Insertion Sort s s s s s s

Mergesort 0.016067s 0.017168s 0.016041s 0.015755s 0.015749s 0.016156s

Quicksort 0.013074s 0.013108s 0.013293s 0.013240s 0.013064s 0.013156s

Heapsort 0.019785s 0.019650s 0.019659s 0.019376s 0.021671s 0.020028s

Table 2.6. Result of the experiment for random input, N = 1000000

Sorting Average
Run 1 Run 2 Run 3 Run 4 Run 5 Time for
Algorithm N = 1000000

1352.6269 1515.0414 1511.2011 1356.3202 1521.0225 1451.2424


Selection Sort 23s 47s 88s 51s 51s 72s

4646.3176 4630.2826 4624.4089 4658.6016 4654.6768 4642.8575


Bubble Sort 42s 99s 81s 54s 77s 71s

1230.1351 1234.2737 1237.9355 1238.6678 1243.9023 1236.9829


Insertion Sort 91s 27s 64s 73s 90s 49s

Mergesort 0.179010s 0.175237s 0.167919s 0.168763s 0.168243s 0.171834s

Quicksort 0.140737s 0.143036s 0.146824s 0.141987s 0.141664s 0.142850s

Heapsort 0.258575s 0.256589s 0.256383s 0.258206s 0.255177s 0.256986s


2.​ Sorted Input Case

Table 3.1. Result of the experiment for sorted input, N = 10

Average
Sorting
Run 1 Run 2 Run 3 Run 4 Run 5 Time for
Algorithm
N = 10

Selection Sort 0.000001s 0.000001s 0.000001s 0.000001s 0.000001s 0.000001s

Bubble Sort 0.000001s 0.000002s 0.000001s 0.000000s 0.000001s 0.000001s

0.0000012
Insertion Sort 0.000002s 0.000002s 0.000001s 0.000000s 0.000001s
s

Mergesort 0.000003s 0.000003s 0.000003s 0.000003s 0.000003s 0.000003s

Quicksort 0.000001s 0.000002s 0.000002s 0.000002s 0.000001s 0.000002s

Heapsort 0.000002s 0.000002s 0.000003s 0.000002s 0.000001s 0.000002s

Table 3.2. Result of the experiment for sorted input, N = 100

Average
Sorting
Run 1 Run 2 Run 3 Run 4 Run 5 Time for
Algorithm
N = 100

Selection Sort 0.000013s 0.000020s 0.000013s 0.000013s 0.000017s 0.000015s

Bubble Sort 0.000001s 0.000001s 0.000001s 0.000001s 0.00001s 0.000003s

Insertion Sort 0.000001s 0.000001s 0.000001s 0.000001s 0.000002s 0.000001s

Mergesort 0.000014s 0.000011s 0.000013s 0.000013s 0.000014s 0.000013s

Quicksort 0.000005s 0.000004s 0.000006s 0.000006s 0.000006s 0.000005s

Heapsort 0.000003s 0.000013s 0.000014s 0.000014s 0.000014s 0.000012s

Table 3.3. Result of the experiment for sorted input, N = 1000

Average
Sorting
Run 1 Run 2 Run 3 Run 4 Run 5 Time for
Algorithm
N = 1000

Selection Sort 0.001006s 0.001760s 0.001125s 0.001259s 0.001133s 0.001257s

Bubble Sort 0.001004s 0.001004s 0.001428s 0.001303s 0.001005s 0.001185s

Insertion Sort 0.000005s 0.000009s 0.000006s 0.000004s 0.000004s 0.000006s

Mergesort 0.000182s 0.000100s 0.000109s 0.000158s 0.000110s 0.000132s

Quicksort 0.000053s 0.000031s 0.000042s 0.000042s 0.000027s 0.000039s

Heapsort 0.000014s 0.000120s 0.000126s 0.000169s 0.000119s 0.000110s


Table 3.4. Result of the experiment for sorted input, N = 10000

Average
Sorting
Run 1 Run 2 Run 3 Run 4 Run 5 Time for
Algorithm
N = 10000

Selection Sort 0.101828s 0.102716s 0.102243s 0.103222s 0.103029s 0.102608s

Bubble Sort 0.100032s 0.100021s 0.100021s 0.100025s 0.100032s 0.100003s

Insertion Sort 0.000026s 0.000041s 0.000042s 0.000041s 0.000041s 0.000038s

Mergesort 0.000861s 0.001281s 0.000898s 0.001371s 0.000825s 0.001047s

Quicksort 0.000534s 0.000534s 0.000545s 0.000329s 0.000352s 0.000459s

Heapsort 0.001273s 0.001821s 0.001951s 0.001185s 0.001636s 0.001573s

Table 3.5. Result of the experiment for sorted input, N = 100000

Sorting Average
Run 1 Run 2 Run 3 Run 4 Run 5 Time for
Algorithm
N = 100000

10.307797 10.231213 10.226707 10.257634 10.448346 10.294339


Selection Sort s s s s s s

10.000322 10.000207 10.000208 10.000335 10.000185


Bubble Sort s s s s s
10.00025s

Insertion Sort 0.000235s 0.000255s 0.000402s 0.000289s 0.000404s 0.000317s

Mergesort 0.009452s 0.008585s 0.011213s 0.008113s 0.009699s 0.009412s

Quicksort 0.004591s 0.004112s 0.004758s 0.004209s 0.005450s 0.004624s

Heapsort 0.014651s 0.014684s 0.013848s 0.014191s 0.015507s 0.014576s

Table 3.6. Result of the experiment for sorted input, N = 1000000

Sorting Average
Run 1 Run 2 Run 3 Run 4 Run 5 Time for
Algorithm N = 1000000

1949.0343 1979.2478 1977.2458 1976.3426 1956.8921 1967.7525


Selection Sort 69s 93s 12s 04s 37s 63s

1493.6670 1501.9695 1504.2200 1487.0313 1485.6846 1,494.514


Bubble Sort 75s 02s 02s 12s 67s 512s

Insertion Sort 0.005787s 0.006768s 0.005810s 0.011487s 0.006219s 0.007214s

Mergesort 0.102037s 0.105638s 0.102985s 0.099648s 0.100487s 0.102159s

Quicksort 0.042786s 0.042221s 0.042383s 0.046103s 0.046103s 0.043919s

Heapsort 0.177655s 0.178766s 0.180230s 0.179358s 0.179812s 0.179164s


B.​ Discussion of Results

Table 4.1. Average running time for a randomly generated array

Selection Bubble Insertion


N Mergesort Quicksort Heapsort
Sort Sort Sort

10 0.000002s 0.000001s 0.000001s 0.000002s 0.000002s 0.000001s

100 0.000024s 0.000024s 0.000014s 0.000012s 0.000008s 0.000010s

1000 0.001539s 0.003078s 0.001003s 0.000105s 0.000082s 0.000125s

10000 0.172584s 0.316973s 0.103641s 0.001281s 0.001058s 0.001519s

100000 16.136238s 47.01584s 10.851988s 0.016156s 0.013156s 0.020028s

1451.24247 4642.85757 1236.98294


1000000 2s 1s 9s
0.171834s 0.142850s 0.256986s

Figure 1.1. Line graph for the average runtimes of a randomly generated array

Figure 1.2. Scatter plot for the average runtime of a randomly generated array
ANALYSIS BASED ON NUMBER OF INPUTS FOR A RANDOMLY GENERATED ARRAY

Small Inputs (N = 10-100)


●​ Based on program execution for small inputs, all sorting algorithms performed
similarly within the microsecond range. Bubble Sort showed a slightly faster
execution, but these differences were negligible.
Medium Inputs (N = 1000-10000)
●​ The O(n2) time complexity of incremental comparison-based sorting algorithms
(Bubble Sort, Insertion Sort, Selection Sort) becomes apparent, showing a clear
performance difference when compared to the O(n log n) recursive algorithms
(Mergesort, Quicksort, Heapsort).
●​ It can also be observed from the data that, during this period, the incremental
comparison-based sorting algorithms are reaching the 0.1-second mark.
Large Inputs (N = 100000)
●​ When the input size reaches this period, incremental comparison-based
algorithms exhibit significantly longer execution times, approximately 10 seconds,
compared to the hundredths of a second required by recursive algorithms.
●​ From the data above, it can be observed that among the incremental
comparison-based sorting algorithms, Bubble Sort has the fastest growth in
execution time due to its multiple swaps per pass, making it significantly slower
than the others.
Extremely Large Inputs (N = 1000000)
●​ In this case, it can be observed that the recursive algorithm dominates in terms of
runtime for large inputs.
●​ Bubble Sort becomes impractical, taking over 4,600 seconds (~1.3 hours), while
Selection Sort takes 1,451 seconds (~24 minutes) and Insertion Sort consumes
1,236 seconds (~20 minutes) to complete sorting an array.
●​ As its name suggests, the Quicksort algorithm remains the fastest among all
sorting algorithms for extremely large inputs.

​ ANALYSIS OF EACH SORTING ALGORITHM FOR A RANDOMLY GENERATED


ARRAY

​ Selection Sort
●​ Selection sort starts off fast but quickly dwindles in performance as the input
increases in number.
●​ Always makes O(n2) swaps, leading to slow performance.
​ Bubble Sort
●​ Demonstrates the least efficient performance for large datasets.
●​ Requires a high number of comparisons and swaps in worst-case scenarios, also
has a time complexity of O(n2).
​ Insertion Sort
●​ Better than Selection and Bubble Sort but remains inefficient for large inputs. For
N = 100000, the execution time was 1236.98 seconds (~20 minutes), significantly
better than Bubble Sort but still slow.
​ Mergesort
●​ Maintains consistent and efficient performance across all input sizes.
●​ Slightly slower than Quicksort but still highly efficient.
​ Quicksort
●​ Represents the fastest sorting algorithm for large datasets.
●​ Demonstrates exceptional speed and efficiency.
​ Heapsort
●​ Exhibits slightly slower performance compared to Mergesort and Quicksort.
●​ Has consistent average performance across five runs.

Table 4.2 Average running time for an already sorted array

Selection Bubble Insertion


N Mergesort Quicksort Heapsort
Sort Sort Sort

10 0.000001s 0.000001s 0.000001s 0.000003s 0.000002s 0.000002s

100 0.000015s 0.000012s 0.000001s 0.000013s 0.000005s 0.000012s

1000 0.001257s 0.001289s 0.000006s 0.000139s 0.000039s 0.000110s

10000 0.102608s 0.100026s 0.000038s 0.001047s 0.000459s 0.001573s

100000 10.294539s 10.002005s 0.000317s 0.009412s 0.004624s 0.014576s

1967.75256 1,494.51451
1000000 3s 2s
0.007214s 0.102159s 0.043919s 0.179164s

Figure 2.1. Line graph for the average runtimes of an already sorted array
Figure 2.2. Scatter plot for the average runtimes of an already sorted array

ANALYSIS BASED ON NUMBER OF INPUTS FOR AN ALREADY SORTED ARRAY

Small Inputs (N = 10 - 100)


●​ For small input sizes, all sorting algorithms perform similarly, with execution times
in the microsecond range. The differences between algorithms are negligible at
this scale.
●​ However, it is clear in this data that there is an outlier, the Insertion Sort which
runs at a much faster rate than other algorithms.
Medium Inputs (N = 1000 - 10000)
●​ For medium inputs, Bubble Sort and Selection Sort algorithms show an increase
in execution time, similar to randomly generated arrays, while the recursive
algorithms maintained a slower growth rate.
●​ In our program, the Quicksort algorithm uses the median-of-three method to
choose a pivot, preventing it from reaching the worst-case scenario of O(n2),
which occurs when the pivot is always the first or last element in the array.
●​ Insertion sort continues its trend of linear growth.
​ Large Inputs (N = 100000)
●​ For large inputs, Selection Sort and Bubble Sort become impractically slow,
taking around 10 seconds to complete. In contrast, Insertion Sort remains
extremely fast due to its adaptive nature, finishing in just 0.000317 seconds.
●​ Recursive sorting algorithms remain efficient, with Quick Sort leading in speed,
followed by Merge Sort and Heap Sort. The differences among these three
algorithms are minimal, but Quick Sort remains the best performer.
Extremely Large Inputs (N = 1000000)
●​ The inefficiency of Selection Sort and Bubble Sort becomes even more apparent
at this stage. Selection Sort takes approximately 1,967 seconds (~32.8 minutes),
while Bubble Sort takes about 1,494 seconds (~24.9 minutes). These times make
both algorithms impractical for large-scale sorting.
●​ Insertion Sort continues to significantly outperform the other algorithms due to its
best-case scenario, completing in just 0.007214 seconds.
●​ Among the recursive sorting algorithms, Quick Sort remains the fastest, followed
closely by Merge Sort and Heap Sort.
●​ It can also be observed that Bubble Sort ran much faster compared to the
randomly generated inputs. This is because, during its runtime, it performed no
swapping operations, making the process significantly faster.

ANALYSIS OF EACH SORTING ALGORITHM FOR AN ALREADY SORTED ARRAY

​ Selection and Bubble Sort


●​ These two sorting algorithms performed very similarly in these situations. With
each element in its correct position, the algorithms made no swaps and simply
iterated through the array. However, despite having an O(n2) time complexity,
they still struggle to process increasing numbers of data elements and perform
only slightly better with randomly sorted inputs.
​ Insertion Sort
●​ Insertion Sort is the outlier among all the sorting algorithms; it performed the best
in this scenario, aligning with its theoretical time complexity of Ω(n) for sorted
inputs. The runtime of this algorithm grows linearly as the input size increases.
●​ This algorithm also avoided element shifting, making the program run more
smoothly.
​ Merge and Heap Sort
●​ These two algorithms performed similarly when sorting ordered arrays, with
Heapsort performing slightly better than Mergesort. Their performance also does
not differ significantly when sorting randomly generated inputs.
​ Quicksort
●​ This algorithm is the fastest among the recursive functions. This is made possible
by the median-of-three method for selecting the pivot, which helps avoid the
worst-case scenario of O(n2).

C.​ Conclusion
​ The empirical analysis of sorting algorithms, conducted on both randomly
generated and incrementally sorted inputs, reveals several key trends and insights. In
the case of sorting randomly generated inputs, the results present a clear distinction
between incremental comparison-based and recursive sorting algorithms. For small
inputs, incremental comparison-based sorting algorithms perform slightly better than
recursive algorithms, however, as the input size increases, the quadratic growth of
algorithms such as Selection, Bubble, and Insertion Sort inflicts overhead to its process,
causing them to become significantly slower. Bubble Sort performs the worst due to
multiple swaps, while Insertion Sort remains the fastest among incremental
comparison-based approaches.
In contrast, recursive algorithms such as Quicksort, Mergesort, and Heapsort
consistently outperform incremental comparison-based algorithms, maintaining
efficiency even for large datasets. In all the algorithms tested, Quicksort emerges as the
best overall performer, having the fastest runtime and slowest growth rate overall for
very large inputs (N ≥ 100,000).
​ For incrementally sorted inputs, Bubble and Selection Sort, despite requiring
fewer swaps, still suffer from O(n2) complexity, making them inefficient for large
datasets. Recursive algorithms maintain stable performance, with Quicksort, Mergesort,
and Heapsort continuing to be efficient. However, the pivot selection strategy in
Quicksort plays a huge role in preventing worst-case scenarios. As observed, Insertion
Sort is the best sorting algorithm for sorted inputs, having a near-linear growth rate.
​ Comparing the two cases, it is evident that the initial order of data significantly
impacts performance, with Insertion Sort benefiting the most from pre-sorted inputs. To
note, Modified Bubble Sort would’ve grown similarly as Insertion Sort but this was not
the case in our program. Also, while Bubble and Selection Sort remain inefficient
regardless of input order, recursive sorting algorithms show minimal variation between
the two cases, reinforcing their reliability for different data distributions.
​ After analyzing the data and comparing results, the theoretical analysis
correlates with the results of the empirical analysis of all the sorting algorithms. For
small to medium inputs (10-1,000), it is recommended to use Selection, Bubble,
Insertion sort but using a recursive algorithm such as Mergesort, Quicksort and
Heapsort also results in similar, albeit slightly slower runtimes. For large datasets
(10,000 and above), recursive algorithms should be preferred. Insertion Sort is the best
choice for nearly sorted inputs. This analysis aligns well with theoretical expectations,
demonstrating the importance of algorithm selection based on input size and data
properties.

D.​ Computer System Specifications


System Model: VivoBook_ASUSLaptop X421EA_S433EA
Processor: 11th Gen Intel(R) Core(TM) i5-1135G7 @ 2.40GHz, 2419 Mhz, 4 Core(s), 8
Logical Processor(s).
OS Name: Microsoft Windows 11 Home Single Language
System Type: x64-based PC (64-bit)
Program Used: Ubuntu v.2404.1.160.0
Installed Physical Memory (RAM): 16.0 GB
IV.​ CHALLENGES AND MEMBER PARTICIPATION
A.​ Challenges Encountered

Table 5. Challenges encountered in making the project

Challenges Encountered Solutions Applied

The program encountered memory Implemented dynamic memory allocation


allocation errors when attempting to for the input array to improve handling of
initialize very large fixed-size arrays, very large inputs (e.g., N = 1,000,000),
causing the program to terminate replacing the static array implementation.
abruptly.

Program execution takes an excessive Monitored the program's execution until


amount of time to complete when sorting termination, where the longest execution
extremely large inputs using incremental required approximately 1.5 hours.
comparison-based sorting algorithms,
especially Bubble Sort, leading the
members to believe that the program was
not functioning (unresponsive).

Our group initially thought that only one The group decided to start over despite
sorting algorithm could run per execution. missing the project deadline. We fixed the
Unfortunately, we discovered this error code first and then restarted the empirical
too late, which prevented us from analysis.
submitting the project on time. As a result,
we had to make significant revisions to
the program before conducting the
empirical analysis again.

B.​ Member Participation

Table 6. Contribution of each member to the project

Name of Member Contribution in the Project

Cadag, Jaycee D. ●​ Implemented the Quicksort algorithm in C


incorporating the median-of-three method for
improved pivot selection and enhanced efficiency.
●​ Debugged and fixed the merge source code by
eliminating redundant function calls and editing
certain lines of code to improve efficiency and reduce
redundancy.
●​ Assisted in organizing screenshots of executed
programs.
●​ Plotted the running times in the table, and calculated
their average.
●​ Assisted in checking and editing some contents.

Dela Cruz, Mark L. ●​ Created a Git repository to provide group members


with convenient access to and version control of
developed programs.
●​ Developed the initial source code for the main
function.
●​ Developed user interface functions for improved user
experience in the terminal.
●​ Executed the sorting program and documented the
runtime of each sorting algorithm across various input
sizes.
●​ Designed and generated all graphical representations
to visually illustrate the performance trends of the
sorting algorithms.
●​ Conducted a comprehensive data analysis,
comparing and contrasting the efficiency of each
algorithm, and formulated conclusions based on the
observed results.

Espinas, A Z Rain L. ●​ Implemented the Selection Sort and Bubble Sort


algorithms in C.
●​ Debugged and fixed the merged source code,
removing unnecessary variables, adding comments
and error-handling, and ensuring proper program
termination for improved readability and efficiency.
●​ Enhanced the program’s final version by removing the
sorting algorithm selection menu and incorporating
functions for duplicating arrays and printing execution
times.
●​ Significantly contributed to drafting and developing
the programming project report. This included the
documentation section that covers the program
overview, specifications, and execution flow, as well
as the report's template and overall layout.
●​ Assisted in drafting and organizing the empirical
analysis section that covers the performance analysis,
discussion of results, and conclusion.
●​ Documented the challenges encountered in making
the project.
●​ Contributed to proofreading the report's final content.

Loviña, John Melrick M. ●​ Implemented the Heapsort algorithm in C.


●​ Assisted in organizing screenshots of executed
programs, plotting some of the running times in the
table, and calculating their average.

Morcozo, Janna Carla R. ●​ Implemented the Insertion Sort and Merge Sort
algorithms in C.
●​ Assembled and integrated the group’s source code
contributions to create the program's initial working
version.
●​ Assisted in organizing screenshots of executed
programs.
●​ Plotting some of the running times in the table, and
calculating their average.
●​ Re-checking content validity and editing.

You might also like