diff --git a/Makefile b/Makefile index c3c65bd..a21acbe 100644 --- a/Makefile +++ b/Makefile @@ -28,6 +28,7 @@ DYNAMIC_BUILD_FILES := $(DYNAMIC_BUILD_DIR)/lsort.o \ $(STATIC_BUILD_DIR)/quicksort.o TEST_BUILD_FILES := $(TEST_BUILD_DIR)/test.o \ + $(TEST_BUILD_DIR)/samples.o \ @@ -40,14 +41,14 @@ dynamic: $(DYNAMIC_BUILD_FILES) $(CC) -shared -o $(DYNAMIC_BUILD_DIR)/liblsort.so $(DYNAMIC_BUILD_FILES) $(DYNAMIC_BUILD_DIR)/%.o: %.c | $(DYNAMIC_BUILD_DIR) - $(CC) $(CFLAGS) -c -fPIC $< -o $@ + $(CC) $(CFLAGS) -I./test/include -c -fPIC $< -o $@ static: $(STATIC_BUILD_FILES) ar rcs $(STATIC_BUILD_DIR)/liblsort.a $(STATIC_BUILD_FILES) $(STATIC_BUILD_DIR)/%.o: %.c | $(STATIC_BUILD_DIR) - $(CC) $(CFLAGS) -c $< -o $@ + $(CC) $(CFLAGS) -I./test/include -c $< -o $@ test: $(TEST_BUILD_FILES) test_dynamic test_static diff --git a/include/lsort.h b/include/lsort.h index 1755533..922ad02 100644 --- a/include/lsort.h +++ b/include/lsort.h @@ -3,6 +3,6 @@ #include "types.h" -int check_sorted(lsort_array_i* array); +int check_sorted(lsort_array* array); #endif \ No newline at end of file diff --git a/include/quicksort.h b/include/quicksort.h index 19f6f2a..c88d5e0 100644 --- a/include/quicksort.h +++ b/include/quicksort.h @@ -3,6 +3,6 @@ #include "types.h" -int lsort_quicksort(lsort_array_i* array, int (*function_pointer)(int, int)); +int lsort_quicksort(lsort_array* array); #endif \ No newline at end of file diff --git a/include/radix.h b/include/radix.h index 144a6a5..27bf162 100644 --- a/include/radix.h +++ b/include/radix.h @@ -3,6 +3,6 @@ #include "types.h" -int lsort_radix(lsort_array_i* array, lsort_array_i* return_array); +int lsort_radix(lsort_array* array, lsort_array* return_array); #endif \ No newline at end of file diff --git a/include/types.h b/include/types.h index 8506bd3..504a38f 100644 --- a/include/types.h +++ b/include/types.h @@ -10,29 +10,34 @@ typedef struct { } lsort_string; typedef struct { - size_t count; - size_t capacity; - int* items; -} lsort_array_i; - - -lsort_array_i* lsort_array_i_create(); -void lsort_array_i_destroy(lsort_array_i* array); - -void lsort_array_i_append(lsort_array_i* array, int number); -int lsort_array_i_swap(lsort_array_i* array, int indexA, int indexB); - -void lsort_array_i_print(lsort_array_i* array); - + int key; + void* value; +} lsort_item; typedef struct { size_t count; size_t capacity; - lsort_array_i** items; -} lsort_array_i_array; + lsort_item** items; +} lsort_array; -void lsort_array_i_array_append(lsort_array_i_array* array, lsort_array_i* item); -void lsort_array_i_array_destroy(lsort_array_i_array* array); +typedef struct { + size_t count; + size_t capacity; + lsort_array** items; +} lsort_array_array; +lsort_item* lsort_item_create(int key, void* value); +lsort_array* lsort_array_create(); +lsort_array_array* lsort_array_array_create(); + +void lsort_item_destroy(lsort_item* item); +void lsort_array_destroy(lsort_array* array, int destroyItems); +void lsort_array_array_destroy(lsort_array_array* array, int destroyItems); + +void lsort_array_append(lsort_array* array, lsort_item* item); +void lsort_array_array_append(lsort_array_array* array, lsort_array* item); + +void lsort_array_clear(lsort_array* array); +int lsort_array_swap(lsort_array* array, int indexA, int indexB); #endif \ No newline at end of file diff --git a/lsort.c b/lsort.c index c34fdbc..bec4198 100644 --- a/lsort.c +++ b/lsort.c @@ -1,9 +1,9 @@ #include "./include/lsort.h" -int check_sorted(lsort_array_i* array) { +int check_sorted(lsort_array* array) { if (array->count <= 0) return 2; for (int i = 0; i < array->count - 1; i++) { - if (array->items[i] > array->items[i + 1]) { + if (array->items[i]->key > array->items[i + 1]->key) { return 1; }; } diff --git a/quicksort.c b/quicksort.c index f2f93e2..895e273 100644 --- a/quicksort.c +++ b/quicksort.c @@ -1,45 +1,36 @@ #include "include/lsort.h" #include "include/types.h" #include "include/quicksort.h" -#include -typedef int (*int_function_pointer)(int, int); - -static int default_compare_function(int a, int b) { - return a - b; -} - -static int partition(lsort_array_i* array, int L, int R, int_function_pointer compare_function) { - int pivot = array->items[R]; +static int partition(lsort_array* array, int L, int R) { + int pivot = array->items[R]->key; int i = L - 1; for (int j = L; j < R; j++) { - if (compare_function(array->items[j], pivot) < 0) { + if (array->items[j]->key < pivot) { i = i + 1; - lsort_array_i_swap(array, i, j); + lsort_array_swap(array, i, j); } } - lsort_array_i_swap(array, i + 1, R); + lsort_array_swap(array, i + 1, R); return i + 1; } -static void _quicksort(lsort_array_i* array, int L, int R, int_function_pointer compare_function) { +static void _quicksort(lsort_array* array, int L, int R) { if (L < R) { - int pivotIndex = partition(array, L, R, compare_function); - _quicksort(array, L, pivotIndex - 1, compare_function); - _quicksort(array, pivotIndex + 1, R, compare_function); + int pivotIndex = partition(array, L, R); + _quicksort(array, L, pivotIndex - 1); + _quicksort(array, pivotIndex + 1, R); } } -int lsort_quicksort(lsort_array_i* array, int_function_pointer compare_function) { +int lsort_quicksort(lsort_array* array) { if (array->count < 1) { return 0; } - if (compare_function == NULL) compare_function = default_compare_function; + _quicksort(array, 0, (int)array->count - 1); - _quicksort(array, 0, (int)array->count - 1, compare_function); - - return check_sorted(array) ? 1 : 0; + return check_sorted(array); } \ No newline at end of file diff --git a/radix.c b/radix.c index 087eaa6..6348acf 100644 --- a/radix.c +++ b/radix.c @@ -1,40 +1,42 @@ +#include "include/lsort.h" #include "include/types.h" #include "include/radix.h" -static int _seperate_pos_neg(lsort_array_i* array, lsort_array_i* pos_array, lsort_array_i* neg_array) { +static int _seperate_pos_neg(lsort_array* array, lsort_array* pos_array, lsort_array* neg_array) { for (int i = 0; i < array->count; i++) { - if ((0x80000000 & array->items[i]) == 0x80000000) { - lsort_array_i_append(neg_array, array->items[i]); + if ((0x80000000 & array->items[i]->key) == 0x80000000) { + lsort_array_append(neg_array, array->items[i]); } else { - lsort_array_i_append(pos_array, array->items[i]); + lsort_array_append(pos_array, array->items[i]); } } return 0; } -static int _sort_items(lsort_array_i* numbers, lsort_array_i_array* buckets) { +static int _sort_items(lsort_array* numbers, lsort_array_array* buckets) { int byte_check = 0x0000000F; for (int i = 0; i < 8; i++) { // Loop through the list of numbers and append them to their respective buckets for this 4-byte chunk for (int item_index = 0; item_index < numbers->count; item_index++) { - int* current_number = &numbers->items[item_index]; - lsort_array_i* bucket = buckets->items[(*current_number >> (i * 4)) & byte_check]; + lsort_item* current_item = numbers->items[item_index]; + lsort_array* bucket = buckets->items[(current_item->key >> (i * 4)) & byte_check]; - lsort_array_i_append(bucket, *current_number); + + lsort_array_append(bucket, current_item); } - numbers->count = 0; + lsort_array_clear(numbers); // Add the bucketed numbers back to the original array after emptying it for (int bucket_number = 0; bucket_number < buckets->count; bucket_number++) { - lsort_array_i* bucket = buckets->items[bucket_number]; + lsort_array* bucket = buckets->items[bucket_number]; for (int bucket_item = 0; bucket_item < bucket->count; bucket_item++) { - lsort_array_i_append(numbers, bucket->items[bucket_item]); + lsort_array_append(numbers, bucket->items[bucket_item]); } - bucket->count = 0; + lsort_array_clear(bucket); } // Repeat for each 4-byte chunk... @@ -43,37 +45,41 @@ static int _sort_items(lsort_array_i* numbers, lsort_array_i_array* buckets) { return 0; } -int lsort_radix(lsort_array_i* array, lsort_array_i* return_array) { +int lsort_radix(lsort_array* array, lsort_array* return_array) { if (array->count <= 0) return 1; // Seperate positive and negative numbers - lsort_array_i positive_numbers = {0}; - lsort_array_i negative_numbers = {0}; + lsort_array* positive_numbers = lsort_array_create(); + lsort_array* negative_numbers = lsort_array_create(); - if (_seperate_pos_neg(array, &positive_numbers, &negative_numbers)) return 2; + if (_seperate_pos_neg(array, positive_numbers, negative_numbers)) return 2; // Create buckets - lsort_array_i_array buckets = {0}; + lsort_array_array* buckets = lsort_array_array_create(); for (int i = 0; i < 16; i++) { - lsort_array_i* bucket = lsort_array_i_create(); - lsort_array_i_array_append(&buckets, bucket); + lsort_array* bucket = lsort_array_create(); + lsort_array_array_append(buckets, bucket); } // Sort each set of numbers using those buckets - _sort_items(&negative_numbers, &buckets); - _sort_items(&positive_numbers, &buckets); + _sort_items(negative_numbers, buckets); + _sort_items(positive_numbers, buckets); + // Add each array of numbers to the return array - for (int i = 0; i < negative_numbers.count; i++) { - lsort_array_i_append(return_array, negative_numbers.items[i]); + for (int i = 0; i < negative_numbers->count; i++) { + lsort_array_append(return_array, negative_numbers->items[i]); } - for (int i = 0; i < positive_numbers.count; i++) { - lsort_array_i_append(return_array, positive_numbers.items[i]); + for (int i = 0; i < positive_numbers->count; i++) { + lsort_array_append(return_array, positive_numbers->items[i]); } + lsort_array_destroy(negative_numbers, 0); + lsort_array_destroy(positive_numbers, 0); + // Destroy the buckets - lsort_array_i_array_destroy(&buckets); + lsort_array_array_destroy(buckets, 0); - return 0; + return check_sorted(return_array); } \ No newline at end of file diff --git a/test/include/samples.h b/test/include/samples.h new file mode 100644 index 0000000..665bf60 --- /dev/null +++ b/test/include/samples.h @@ -0,0 +1,8 @@ +#ifndef LSORTTEST_SAMPLES_H +#define LSORTTEST_SAMPLES_H + +#include "../../include/types.h" + +lsort_array* generate_samples(int number); + +#endif \ No newline at end of file diff --git a/test/samples.c b/test/samples.c new file mode 100644 index 0000000..1c8bb19 --- /dev/null +++ b/test/samples.c @@ -0,0 +1,15 @@ +#include "../include/types.h" +#include "include/samples.h" +#include +#include + +lsort_array* generate_samples(int number) { + srand(time(NULL)); + lsort_array* array = lsort_array_create(); + + for (int i = 0; i < number; i++) { + lsort_array_append(array, lsort_item_create(rand(), NULL)); + } + + return array; +}; \ No newline at end of file diff --git a/test/test.c b/test/test.c index daaa227..3627dc3 100644 --- a/test/test.c +++ b/test/test.c @@ -1,105 +1,94 @@ #include "../include/types.h" #include "../include/radix.h" #include "../include/quicksort.h" -#include "../include/lsort.h" +#include "include/samples.h" #include -int test_array_i_append(lsort_array_i* array) { - printf("lsort_array_i_append()...\n"); +#define sample_count 64*64*64*64 - lsort_array_i_append(array, 25); - lsort_array_i_append(array, 64); - lsort_array_i_append(array, 34); - lsort_array_i_append(array, 74); - lsort_array_i_append(array, 99); - lsort_array_i_append(array, 23); +int test_array_append() { + printf("lsort_array_append()...\n"); - if (array->items[5] != 23) return 1; + int return_code = 0; + lsort_array* array = lsort_array_create(); - return 0; + lsort_array_append(array, lsort_item_create(25, NULL)); + lsort_array_append(array, lsort_item_create(64, NULL)); + lsort_array_append(array, lsort_item_create(34, NULL)); + lsort_array_append(array, lsort_item_create(74, NULL)); + lsort_array_append(array, lsort_item_create(99, NULL)); + lsort_array_append(array, lsort_item_create(23, NULL)); + + + if (array->items[5]->key != 23) return_code = 1; + + lsort_array_destroy(array, 1); + return return_code; } -int test_array_i_swap(lsort_array_i* array) { - printf("lsort_array_i_swap()...\n"); +int test_array_swap() { + printf("lsort_array_swap()...\n"); - lsort_array_i_swap(array, 0, 5); - lsort_array_i_swap(array, 4, 2); - lsort_array_i_swap(array, 2, 3); + int return_code = 0; + lsort_array* array = lsort_array_create(); + + lsort_array_append(array, lsort_item_create(25, NULL)); + lsort_array_append(array, lsort_item_create(64, NULL)); + lsort_array_append(array, lsort_item_create(34, NULL)); + lsort_array_append(array, lsort_item_create(74, NULL)); + lsort_array_append(array, lsort_item_create(99, NULL)); + lsort_array_append(array, lsort_item_create(23, NULL)); + + int index_0 = array->items[0]->key; + int index_1 = array->items[1]->key; + int index_2 = array->items[2]->key; + int index_3 = array->items[3]->key; + int index_4 = array->items[4]->key; + int index_5 = array->items[5]->key; + + lsort_array_swap(array, 0, 5); + lsort_array_swap(array, 4, 2); + lsort_array_swap(array, 2, 3); - if (array->items[0] != 23 || array->items[5] != 25 || array->items[4] != 34 || array->items[2] != 74 || array->items[3] != 99) return 1; + if ( + array->items[0]->key != index_5 || + array->items[5]->key != index_0 || + array->items[4]->key != index_2 || + array->items[3]->key != index_4 || + array->items[2]->key != index_3 || + array->items[1]->key != index_1 + ) return_code = 1; - return 0; -} + lsort_array_destroy(array, 1); -int test_append_swap() { - printf("test_append_swap()...\n"); - - lsort_array_i array_append_swap = {0}; - - if (test_array_i_append(&array_append_swap)) return 1; - if (test_array_i_swap(&array_append_swap)) return 1; - - lsort_array_i array_sort_check = {0}; - lsort_array_i_append(&array_sort_check, 1); - lsort_array_i_append(&array_sort_check, 5); - lsort_array_i_append(&array_sort_check, 7); - lsort_array_i_append(&array_sort_check, 8); - lsort_array_i_append(&array_sort_check, 15); - lsort_array_i_append(&array_sort_check, 28); - - if (check_sorted(&array_sort_check) == 1) return 1; - lsort_array_i_swap(&array_sort_check, 2, 4); - lsort_array_i_swap(&array_sort_check, 0, 3); - if (check_sorted(&array_sort_check) == 0) return 1; - - return 0; + return return_code; } int test_radix_sort() { printf("lsort_radix()...\n"); - lsort_array_i array_radix = {0}; - lsort_array_i_append(&array_radix, -2); - lsort_array_i_append(&array_radix, -15); - lsort_array_i_append(&array_radix, 25); - lsort_array_i_append(&array_radix, 56); - lsort_array_i_append(&array_radix, 23); - lsort_array_i_append(&array_radix, -222); - lsort_array_i_append(&array_radix, -58); + lsort_array* array_radix = generate_samples(sample_count); + lsort_array* array_radix_return = lsort_array_create(); + int return_code = lsort_radix(array_radix, array_radix_return); - lsort_array_i array_radix_return = {0}; - lsort_radix(&array_radix, &array_radix_return); - - if (check_sorted(&array_radix_return) != 0) return 1; - - return 0; + lsort_array_destroy(array_radix, 1); + return return_code; } int test_quicksort() { printf("lsort_quicksort()...\n"); - lsort_array_i array_quicksort = {0}; - lsort_array_i_append(&array_quicksort,6); - lsort_array_i_append(&array_quicksort, 5); - lsort_array_i_append(&array_quicksort, 4); - lsort_array_i_append(&array_quicksort, 3); - lsort_array_i_append(&array_quicksort, 2); - lsort_array_i_append(&array_quicksort, 5); - lsort_array_i_append(&array_quicksort, 1); - lsort_array_i_append(&array_quicksort, 0); - - lsort_quicksort(&array_quicksort, NULL); + lsort_array* array_quicksort = generate_samples(sample_count); + int return_code = lsort_quicksort(array_quicksort); - if (check_sorted(&array_quicksort)) return 1; - - - return 0; + lsort_array_destroy(array_quicksort, 1); + return return_code; } int main(void) { - if ( - test_append_swap() || + test_array_append() || + test_array_swap() || test_radix_sort() || test_quicksort() ) return 1; @@ -107,4 +96,4 @@ int main(void) { printf("\nTest completed successfully.\n"); return 0; -} +} \ No newline at end of file diff --git a/types.c b/types.c index ebf1fd5..0afb94d 100644 --- a/types.c +++ b/types.c @@ -1,16 +1,57 @@ #include "include/types.h" #include -#include +// #include -lsort_array_i* lsort_array_i_create() { - return calloc(1, sizeof(lsort_array_i)); +lsort_item* lsort_item_create(int key, void* value) { + lsort_item* item = calloc(1, sizeof(lsort_item)); + item->key = key; + item->value = value; + + return item; +}; + +lsort_array* lsort_array_create() { + return calloc(1, sizeof(lsort_array)); } -void lsort_array_i_destroy(lsort_array_i* array) { +lsort_array_array* lsort_array_array_create() { + return calloc(1, sizeof(lsort_array_array)); +} + + +void lsort_item_destroy(lsort_item* item) { + free(item->value); + item->value = NULL; + + free(item); + item = NULL; +}; + +void lsort_array_destroy(lsort_array* array, int destroyItems) { + if (destroyItems) { + for (int i = 0; i < array->count; i++) { + lsort_item_destroy(array->items[i]); + } + } + free(array->items); + array->items = NULL; + free(array); } -void lsort_array_i_append(lsort_array_i* array, int item) { +void lsort_array_array_destroy(lsort_array_array* array, int destroyItems) { + for (int array_number = 0; array_number < array->count; array_number++) { + lsort_array_destroy(array->items[array_number], destroyItems); + } + free(array->items); + array->items = NULL; + + free(array); + array = NULL; +} + + +void lsort_array_append(lsort_array* array, lsort_item* item) { if (array->count >= array->capacity) { if (array->capacity == 0) array->capacity = 8; else array->capacity *= 2; @@ -20,34 +61,29 @@ void lsort_array_i_append(lsort_array_i* array, int item) { array->items[array->count++] = item; } -int lsort_array_i_swap(lsort_array_i* array, int indexA, int indexB) { +void lsort_array_array_append(lsort_array_array* array, lsort_array* item) { + if (array->count >= array->capacity) { + if (array->capacity == 0) array->capacity = 8; + else array->capacity *= 2; + + array->items = realloc(array->items, array->capacity * sizeof(*array->items)); + } + array->items[array->count++] = item; +} + + +void lsort_array_clear(lsort_array* array) { + free(array->items); + array->items = NULL; + array->count = 0; + array->capacity = 0; +} + +int lsort_array_swap(lsort_array* array, int indexA, int indexB) { if (indexA > array->count - 1 || indexB > array->count - 1) return 1; - int temp = array->items[indexA]; + lsort_item* temp = array->items[indexA]; array->items[indexA] = array->items[indexB]; array->items[indexB] = temp; - + return 0; -} - -void lsort_array_i_print(lsort_array_i* array) { - for (int i = 0; i < array->count; i++) { - printf("%d ", array->items[i]); - } - printf("\n"); -} - -void lsort_array_i_array_append(lsort_array_i_array* array, lsort_array_i* item) { - if (array->count >= array->capacity) { - if (array->capacity == 0) array->capacity = 8; - else array->capacity *= 2; - - array->items = realloc(array->items, array->capacity * sizeof(*array->items)); - } - array->items[array->count++] = item; -} - -void lsort_array_i_array_destroy(lsort_array_i_array* array) { - for (int array_number = 0; array_number < array->count; array_number++) { - lsort_array_i_destroy(array->items[array_number]); - } } \ No newline at end of file