diff --git a/array_backed_list.c b/array_backed_list.c index 02d0fe7..49594ea 100644 --- a/array_backed_list.c +++ b/array_backed_list.c @@ -1,9 +1,9 @@ /*---------------------------------------------------------- - * HTBLA-Leonding / Class: + * HTBLA-Leonding / Class: 2IHIF * --------------------------------------------------------- - * Exercise Number: S06 + * Exercise Number: S04 * Title: Array backed List implementation - * Author: */;/* + * Author: Marc Tismonar * ---------------------------------------------------------- * Description: * Implementation of an array backed list. @@ -50,6 +50,9 @@ /** The implementation of list data: payload-buffer, capacity, size */ struct IntListData { + int* buffer; + int capacity; + int size; }; /* ===================================================================== */ @@ -60,6 +63,289 @@ struct IntListData { * Hint: memcpy may be used to copy all bytes(!) from the existing to the new buffer */ static void increase_buffer(IntList list, unsigned int additional_capacity) { + if (list->buffer == 0) { + list->buffer = alloc_mem(sizeof(int) * additional_capacity); + if (list->buffer != 0) { + list->capacity = additional_capacity; + } + } else { + int* new_buffer = alloc_mem(sizeof(int) * (list->capacity + additional_capacity)); + if (new_buffer != 0) { + for (int i = 0; i < list->size; i++) { + new_buffer[i] = list->buffer[i]; + } + + free_mem(list->buffer); + list->buffer = new_buffer; + list->capacity += additional_capacity; + } + } } /* ===================================================================== */ + +/** + * Obtains ('creates') and provides a 'new' list instance. + * Any list obtained via this function MUST be released using + * function `release_list()`. + * + * Note: This function does not make any assumptions + * about how list components, esp. nodes, are allocated. + * + * @return The list instance or 0, if no list could by instantiated. + */ +IntList list_obtain() { + IntList list = alloc_mem(sizeof(struct IntListData)); + if (list != 0) { + list->buffer = 0; + list->capacity = 0; + list->size = 0; + } + + return list; +} + +/** + * Releases a list that was obtained earlier via function `obtain_list`. + * Released lists MUST NOT be used anymore. + * + * Note: The implementation of this function does not make any assumptions + * about the allocation method of list elements, but MUST match the implementation + * of function `obtain_list` as its inverse function. + * + * @param p_list The pointer to the list to release. The value of the pointer + * is set to 0, if the list was successfully released, otherwise it is left untouched. + */ +void list_release(IntList* p_list) { + if (p_list != 0 && *p_list != 0) { + IntList list = *p_list; + if (list->buffer != 0) { + free_mem(list->buffer); + } + + free_mem(list); + *p_list = 0; + } +} + +/** + * Determines whether or not the given list is valid. + * + * @param list The list to evaluate. + * @return `True` if the list is valid, false otherwise. + */ +bool list_is_valid(IntList list) { + return list != 0; +} + +/** + * Determines whether or not the list contains at least one item. + * + * @param list The list to evaluate. + * @return `False` if the list contains one or more items, `true` otherwise. + */ +bool list_is_empty(IntList list) { + return !list_is_valid(list) || list->size == 0; +} + +/** + * Provides the number of values stored in the list. + * + * @param list The list to evaluate. + * @return The number of values the list contains. + */ +int list_get_size(IntList list) { + return list_is_valid(list) ? list->size : 0; +} + +/** + * Determines whether or not the list given list contains the queried value + * at least once. + * + * @param list The list to query. + * @param value The value. + * @return `True` if the list contains at least one instance of the value, + * `false ` otherwise. + */ +bool list_contains(IntList list, int value) { + if (list_is_valid(list)) { + for (int i = 0; i < list->size; i++) { + if (list->buffer[i] == value) { + return true; + } + } + } + + return false; +} + +/** + * Provides the value stored in the list at the given position. + * + * @param list The list from which the value shall be retrieved. + * @param index The zero-based position index of the value to retrieve. + * @return The value stored at the given position or 0, if the position + * is not available. + */ +int list_get_at(IntList list, unsigned int index) { + if (list_is_valid(list) && index < list->size) { + return list->buffer[index]; + } + + return 0; +} + +/** + * Inserts the given value at the end of the given list. + * + * @param list The list to which the value shall be appended. + * @param value The value to append to the list. + */ +void list_insert(IntList list, int value) { + if (list_is_valid(list)) { + if (list->size >= list->capacity) { + increase_buffer(list, CAPACITY_INCREMENT); + } + + list->buffer[list->size] = value; + list->size++; + } +} + +/** + * Inserts the given value at the indexed position in a way the + * the inserted value is on that position. The index is + * - similar to arrays - zero-based. If the the list is shorter + * than the indexed position, the value is inserted at the end + * of the list. + * + * @param list The list into which the value shall be appended. + * @param index The position index of the value to insert. + * @param value The value to insert. + */ +void list_insert_at(IntList list, unsigned int index, int value) { + if (list_is_valid(list)) { + if (index >= list->size) { + list_insert(list, value); + } else { + if (list->size >= list->capacity) { + increase_buffer(list, CAPACITY_INCREMENT); + } + + for (int i = list->size; i > index; i--) { + list->buffer[i] = list->buffer[i - 1]; + } + + list->buffer[index] = value; + list->size++; + } + } +} + +/** + * Appends the `list_to_append` at the end of the given `list`. + * The appended list is empty afterwards, because all nodes of that list + * have been transferred to `list`. + * + * @param list The list that receives the other list. + * @param list_to_append The list that is appended to `list`. + */ +/* This function is not required in this assignment. */ +/* void list_append(IntList list, IntList list_to_append); */ + +/** + * Removes the first occurrance of `value` from the given list. + * If the list does not contain that value, the list shall not + * be modified. + * + * @param list The list from which the given value shall be removed. + * @param value The value to remove from the list. + */ +void list_remove(IntList list, int value) { + if (list_is_valid(list)) { + for (int i = 0; i < list->size; i++) { + if (list->buffer[i] == value) { + for (int j = i; j < list->size - 1; j++) { + list->buffer[j] = list->buffer[j + 1]; + } + + list->size--; + return; + } + } + } +} + +/** + * Removes all occurrances of `value` from the list. + * If the list does not contain that value, the list shall not + * be modified. + * + * @param list The list from which all occurrances of `value` shall be removed. + * @param value The `value` to remove throughout the list. + */ +void list_remove_all(IntList list, int value) { + if (list_is_valid(list)) { + for (int i = 0; i < list->size; i++) { + if (list->buffer[i] == value) { + for (int j = i; j < list->size - 1; j++) { + list->buffer[j] = list->buffer[j + 1]; + } + + list->size--; + i--; + } + } + } +} + +/** + * Removes the value at the indexed position from the given list + * and provides that value. If the list does not have a value + * at that position, the list remains unmodified. + * + * @param list The list from which the value at the given index shall be returned. + * @param index The zero-based index of the value to return. + * @return The removed value or 0 in case of errors. + */ +int list_remove_at(IntList list, unsigned int index) { + if (list_is_valid(list) && index < list->size) { + int value = list->buffer[index]; + for (int i = index; i < list->size - 1; i++) { + list->buffer[i] = list->buffer[i + 1]; + } + + list->size--; + return value; + } + + return 0; +} + +/** + * Swaps the values at the given indexes, so that value at fst_idx becomes + * the value at snd_idx and vice versa. The invocation is ignored, if the + * list is invalid or at least one of the given indexes is out of range. + * + * @param list The list to manipulate + * @param fst_idx The index of the first item to swap. + * @param snd_idx The index of the second item to swap. + */ +void list_swap(IntList list, unsigned int fst_idx, unsigned int snd_idx) { + if (list_is_valid(list) && fst_idx < list->size && snd_idx < list->size) { + int temp = list->buffer[fst_idx]; + list->buffer[fst_idx] = list->buffer[snd_idx]; + list->buffer[snd_idx] = temp; + } +} + +/** + * Clears the given list by removing all values from the list. + * + * @param list The list to clear. + */ +void list_clear(IntList list) { + if (list_is_valid(list)) { + list->size = 0; + } +} \ No newline at end of file diff --git a/bubble_sort.c b/bubble_sort.c index b2e9c33..3eb1398 100644 --- a/bubble_sort.c +++ b/bubble_sort.c @@ -1,9 +1,9 @@ /*----------------------------------------------------------------------------- * HTBLA-Leonding *----------------------------------------------------------------------------- - * Exercise Number: S06 + * Exercise Number: S05 * Title: Bubble sort implementation - * Author: */;/* + * Author: Marc Tismonar *----------------------------------------------------------------------------- * Description: * Implements the bubble sort strategy @@ -12,3 +12,51 @@ #include "bubble_sort.h" +/** + * Sorts the given list according to the bubble sort strategy. + * + * @param list The list to be sorted. + * @param criterion The pointer to the function that implements the sorting criterion. + * That function accepts two integer parameters and returns a boolean value. + */ +void bubble_sort_list(IntList list, criterion_fn criterion) { + if (!list_is_valid(list) || criterion == 0) { + return; + } + + int size = list_get_size(list); + if (size <= 1) { + return; + } + + for (int i = 0; i < size - 1; i++) { + int swapped = 0; + + for (int j = 0; j < size - i - 1; j++) { + int current = list_get_at(list, j); + int next = list_get_at(list, j + 1); + + if (!criterion(current, next)) { + list_swap(list, j, j + 1); + swapped = 1; + } + } + + if (!swapped) { + break; + } + } +} + +/** + * Sorts the given array according to the bubble sort strategy. + * + * @param array The array to be sorted. + * @param length The length of the array. + * @param criterion The pointer to the function that implements the sorting criterion. + * That function accepts two integer parameters and returns a boolean value. + */ +void bubble_sort_array(int array[], int length, criterion_fn criterion) { + +} + diff --git a/bubble_sort.h b/bubble_sort.h index e80fcb9..f7480e3 100644 --- a/bubble_sort.h +++ b/bubble_sort.h @@ -1,9 +1,9 @@ /*---------------------------------------------------------- * HTBLA-Leonding * --------------------------------------------------------- - * Exercise Number: S06 + * Exercise Number: S05 * Title: Bubble sort - * Author: */;/* + * Author: Marc Tismonar * ---------------------------------------------------------- * Description: * Implements the bubble sort strategy @@ -24,7 +24,7 @@ * @param criterion The pointer to the function that implements the sorting criterion. * That function accepts two integer parameters and returns a boolean value. */ -void bubble_sort_list(); +void bubble_sort_list(IntList list, criterion_fn criterion); /** * Sorts the given array according to the bubble sort strategy. @@ -34,6 +34,6 @@ void bubble_sort_list(); * @param criterion The pointer to the function that implements the sorting criterion. * That function accepts two integer parameters and returns a boolean value. */ -void bubble_sort_array(); +void bubble_sort_array(int array[], int length, criterion_fn criterion); #endif diff --git a/insertion_sort.c b/insertion_sort.c index 3c63750..1c3a8b1 100644 --- a/insertion_sort.c +++ b/insertion_sort.c @@ -1,13 +1,53 @@ /*----------------------------------------------------------------------------- * HTBLA-Leonding *----------------------------------------------------------------------------- - * Exercise Number: S06 + * Exercise Number: S05 * Title: Insertion sort implementation - * Author: */;/* + * Author: Marc Tismonar *----------------------------------------------------------------------------- * Description: * Implements the insertion sort strategy *----------------------------------------------------------------------------- */ -#include "insertion_sort.h" \ No newline at end of file +#include "insertion_sort.h" + +/** + * Sorts the given list according to the insertion sort strategy. + * + * @param list The list to be sorted. + * @param criterion The pointer to the function that implements the sorting criterion. + * That function accepts two integer parameters and returns a boolean value. + */ +void insertion_sort_list(IntList list, criterion_fn criterion) { + if (!list_is_valid(list) || criterion == 0) { + return; + } + + int size = list_get_size(list); + if (size <= 1) { + return; + } + + for (int i = 1; i < size; i++) { + int current = list_get_at(list, i); + int j = i - 1; + + while (j >= 0 && !criterion(list_get_at(list, j), current)) { + list_swap(list, j, j + 1); + j--; + } + } +} + +/** + * Sorts the given array according to the insertion sort strategy. + * + * @param array The array to be sorted. + * @param length The length of the array. + * @param criterion The pointer to the function that implements the sorting criterion. + * That function accepts two integer parameters and returns a boolean value. + */ +void insertion_sort_array(int array[], int length, criterion_fn criterion) { + +} \ No newline at end of file diff --git a/insertion_sort.h b/insertion_sort.h index 58c61d5..bcff586 100644 --- a/insertion_sort.h +++ b/insertion_sort.h @@ -1,9 +1,9 @@ /*---------------------------------------------------------- * HTBLA-Leonding * --------------------------------------------------------- - * Exercise Number: S06 + * Exercise Number: S05 * Title: Insertion sort - * Author: */;/* + * Author: Marc Tismonar * ---------------------------------------------------------- * Description: * Implements the insertion sort strategy @@ -24,7 +24,7 @@ * @param criterion The pointer to the function that implements the sorting criterion. * That function accepts two integer parameters and returns a boolean value. */ -void insertion_sort_list(); +void insertion_sort_list(IntList list, criterion_fn criterion); /** * Sorts the given array according to the insertion sort strategy. @@ -34,6 +34,6 @@ void insertion_sort_list(); * @param criterion The pointer to the function that implements the sorting criterion. * That function accepts two integer parameters and returns a boolean value. */ -void insertion_sort_array(); +void insertion_sort_array(int array[], int length, criterion_fn criterion); #endif diff --git a/sorting.c b/sorting.c index b27dc08..a1aa8bc 100644 --- a/sorting.c +++ b/sorting.c @@ -1,9 +1,9 @@ /*----------------------------------------------------------------------------- - * HTBLA-Leonding / Class: + * HTBLA-Leonding / Class: 2IHIF *----------------------------------------------------------------------------- - * Exercise Number: S06 + * Exercise Number: S05 * Title: Sorting support functions - * Author: */;/* + * Author: Marc Tismonar *----------------------------------------------------------------------------- * Description: * Basic support functions for sorting @@ -32,5 +32,97 @@ * Limit random value to `MAX_VALUE` as defined in `config.h` */ +static int is_random_initialized = 0; + +/** + * Provides the name of the given sorting algorithm. + * + * @param algorithm The sorting algorithm + * @return The name of the algorithm. + */ +char* get_algorithm_name(SortingAlgorithm algorithm) { + switch (algorithm) { + case BUBBLE_SORT: + return "Bubble Sort"; + case INSERTION_SORT: + return "Insertion Sort"; + default: + return "Unknown Algorithm"; + } +} + +/** + * Initializes the given list with random elements. + * + * @param list The list to initialize. + * @param item_count The number of items to insert. + */ +void init_list_random(IntList list, int item_count) { + if (!list_is_valid(list)) { + return; + } + + if (!is_random_initialized) { + srandom(time(NULL)); + is_random_initialized = 1; + } + + list_clear(list); + + for (int i = 0; i < item_count; i++) { + int random_value = random() % (MAX_VALUE + 1); + list_insert(list, random_value); + } +} + +/** + * Prints the values stored in the given list. + * + * @param prefix The optional text to print before values are printed. + * @param list The list to dump. + */ +void print_list(char* prefix, IntList list) { + if (!list_is_valid(list)) { + return; + } + + if (prefix != NULL) { + printf("%s", prefix); + } + + printf("["); + for (int i = 0; i < list_get_size(list); i++) { + printf("%d", list_get_at(list, i)); + if (i < list_get_size(list) - 1) { + printf(", "); + } + } + printf("]\n"); +} + +/** + * Sorts the given list using the given sorting algorithm. + * + * @param list The list to sort. + * @param algorithm The sorting algorithm to use. + * @param criterion The pointer to the function that implements the sorting criterion. + * That function accepts two integer parameters and returns a boolean value. + */ +void sort_list(IntList list, SortingAlgorithm algorithm, criterion_fn criterion) { + if (!list_is_valid(list)) { + return; + } + + switch (algorithm) { + case BUBBLE_SORT: + bubble_sort_list(list, criterion); + break; + case INSERTION_SORT: + insertion_sort_list(list, criterion); + break; + default: + break; + } +} diff --git a/sorting.h b/sorting.h index 9eecb1c..95b6da5 100644 --- a/sorting.h +++ b/sorting.h @@ -1,9 +1,9 @@ /*---------------------------------------------------------- * HTBLA-Leonding * --------------------------------------------------------- - * Exercise Number: S06 + * Exercise Number: S05 * Title: Sorting support functions - * Author: */;/* + * Author: Marc Tismonar * ---------------------------------------------------------- * Description: * Interface for sorting algorithms @@ -26,7 +26,6 @@ typedef enum { BUBBLE_SORT, FIRST_ALGORITHM = BUBBLE_SORT, INSERTION_SORT, - MERGE_SORT, ALGORITHM_ENUM_END } SortingAlgorithm; @@ -36,7 +35,7 @@ typedef enum { * @param algorithm The sorting algorithm * @return The name of the algorithm. */ - get_algorithm_name(); +char* get_algorithm_name(SortingAlgorithm algorithm); #ifdef LIST_VARIANT @@ -47,7 +46,7 @@ typedef enum { * @param list The list to initialize. * @param item_count The number of items to insert. */ -void init_list_random(); +void init_list_random(IntList list, int item_count); /** * Prints the values stored in the given list. @@ -65,7 +64,7 @@ void print_list(char* prefix, IntList list); * @param criterion The pointer to the function that implements the sorting criterion. * That function accepts two integer parameters and returns a boolean value. */ -void sort_list(); +void sort_list(IntList list, SortingAlgorithm algorithm, criterion_fn criterion); #else /* ARRAY_VARIANT */ diff --git a/sorting_criteria.c b/sorting_criteria.c index 85c6527..3190c88 100644 --- a/sorting_criteria.c +++ b/sorting_criteria.c @@ -1,9 +1,9 @@ /*----------------------------------------------------------------------------- - * HTBLA-Leonding / Class: + * HTBLA-Leonding / Class: 2IHIF *----------------------------------------------------------------------------- - * Exercise Number: S06 + * Exercise Number: S05 * Title: Sorting criteria - * Author: */;/* + * Author: Marc Tismonar *----------------------------------------------------------------------------- * Description: * Implementation of sorting criteria @@ -11,3 +11,25 @@ */ #include "sorting_criteria.h" + +/** + * Determines whether or not `fst` is smaller than or equal to `snd` (ascending order). + * + * @param fst The value that is supposed being smaller than `snd`. + * @param snd The value to compare. + * @return True if `fst` is smaller than or equal to `snd`, false otherwise. + */ +bool is_in_asc_order(int fst, int snd) { + return fst <= snd; +} + +/** + * Determines whether or not `fst` is greater than or equal to `snd` (descending order). + * + * @param fst The value that is supposed being greater than `snd`. + * @param snd The value to compare. + * @return True if `fst` is greater than or equal to `snd`, false otherwise. + */ +bool is_in_desc_order(int fst, int snd) { + return fst >= snd; +} diff --git a/sorting_criteria.h b/sorting_criteria.h index 42d2914..7833757 100644 --- a/sorting_criteria.h +++ b/sorting_criteria.h @@ -1,9 +1,9 @@ /*---------------------------------------------------------- * HTBLA-Leonding * --------------------------------------------------------- - * Exercise Number: S06 + * Exercise Number: S05 * Title: Sorting criteria - * Author: */;/* + * Author: Marc Tismonar * ---------------------------------------------------------- * Description: * Interface for sorting algorithms @@ -11,39 +11,40 @@ */ -#ifndef ___SORTING_CRITERIA_H -#define ___SORTING_CRITERIA_H - -#include - -/** - * Declaration of function pointer for comparison function. - * A criterion function determines whether or not the given - * values are in the order that is defined by the criterion. - * - * @param int The value that is supposed being ordered before `snd`. - * @param int The value that is supposed being ordered after `fst`. - * @return True if `fst` IS actually ordered before `snd` - * (the values are in order), false otherwise. - */ -/* Note: Name the pointer type 'criterion_fn' */ - -/** - * Determines whether or not `fst` is smaller than or equal to `snd` (ascending order). - * - * @param fst The value that is supposed being smaller than `snd`. - * @param snd The value to compare. - * @return True if the criterion is satisfied, false otherwise. - */ - is_in_asc_order(); - -/** - * Determines whether or not `fst` is larger than or equal to `snd` (descending order). - * - * @param fst The value that is supposed being smaller than `snd`. - * @param snd The value to compare. - * @return True if the criterion is satisfied, false otherwise. - */ - is_in_desc_order(i); - -#endif \ No newline at end of file + #ifndef ___SORTING_CRITERIA_H + #define ___SORTING_CRITERIA_H + + #include + + /** + * Declaration of function pointer for comparison function. + * A criterion function determines whether or not the given + * values are in the order that is defined by the criterion. + * + * @param int The value that is supposed being ordered before `snd`. + * @param int The value that is supposed being ordered after `fst`. + * @return True if `fst` IS actually ordered before `snd` + * (the values are in order), false otherwise. + */ + /* Note: Name the pointer type 'criterion_fn' */ + typedef bool (*criterion_fn)(int fst, int snd); + + /** + * Determines whether or not `fst` is smaller than or equal to `snd` (ascending order). + * + * @param fst The value that is supposed being smaller than `snd`. + * @param snd The value to compare. + * @return True if the criterion is satisfied, false otherwise. + */ + bool is_in_asc_order(int fst, int snd); + + /** + * Determines whether or not `fst` is larger than or equal to `snd` (descending order). + * + * @param fst The value that is supposed being greater than `snd`. + * @param snd The value to compare. + * @return True if the criterion is satisfied, false otherwise. + */ + bool is_in_desc_order(int fst, int snd); + + #endif \ No newline at end of file diff --git a/stopwatch.c b/stopwatch.c index 56f3dc1..10c19d3 100644 --- a/stopwatch.c +++ b/stopwatch.c @@ -1,9 +1,9 @@ /*----------------------------------------------------------------------------- - * HTBLA-Leonding / Class: + * HTBLA-Leonding / Class: 2IHIF *----------------------------------------------------------------------------- - * Exercise Number: S06 + * Exercise Number: S05 * Title: Stopwatch - * Author: */;/* + * Author: Marc Tismonar *----------------------------------------------------------------------------- * Description: * Implementation of a simple stopwatch @@ -25,3 +25,71 @@ * -> seconds = ticks / CLOCK_PER_SEC * microseconds are s * 10^-6 */ + +static clock_t start_time = 0; +static clock_t passed_time = 0; +static bool is_active = false; + +/** + * Starts taking the time. This function always starts at 0. + */ +void stopwatch_start() +{ + start_time = clock(); + passed_time = 0; + is_active = true; +} + +/** + * Stops or pauses taking the time. Time measurement can be resumed + * via `stopwatch_resume`. + */ +void stopwatch_stop() +{ + if (!is_active) { + return; + } + + passed_time += clock() - start_time; + is_active = false; +} + +/** + * Resumes taking the time. The previously measured time value is + * used as start value. + */ +void stopwatch_resume() +{ + if (is_active) { + return; + } + + start_time = clock(); + is_active = true; +} + +/** + * Determines whether or not the stopwatch takes the time. + * @return True if the stopwatch is measuring, false otherwise. + */ +bool stopwatch_is_active() +{ + return is_active; +} + +/** + * The measured time in microseconds. + * + * @return Either the processor time elapsed since start_stopwatch() has been called or + * the processor time elapsed between the calls of start_stopwatch() and stop_stopwatch(). + */ +double stopwatch_get_elapsed_time() +{ + clock_t total_time = passed_time; + + if (is_active) { + total_time += clock() - start_time; + } + + return ((double)total_time / CLOCKS_PER_SEC) * 1000000.0; +} \ No newline at end of file diff --git a/stopwatch.h b/stopwatch.h index 0d1be6e..1d9cf89 100644 --- a/stopwatch.h +++ b/stopwatch.h @@ -3,7 +3,7 @@ * --------------------------------------------------------- * Exercise Number: S06 * Title: Stopwatch - * Author: */;/* + * Author: Marc Tismonar * ---------------------------------------------------------- * Description: * A stop watch to measure CPU time