Added Quicksort implementation for generic data types.

This commit is contained in:
2025-11-07 16:54:21 +01:00
parent 9b9eff72e6
commit 1589a7d84f
5 changed files with 598 additions and 14 deletions

173
README.md
View File

@@ -206,6 +206,7 @@ The `Vector` data structure supports the following methods:
- `vector_result_t vector_push(vector, value)`: add a new value to the vector; - `vector_result_t vector_push(vector, value)`: add a new value to the vector;
- `vector_result_t vector_set(vector, index, value)`: update the value of a given index if it exists; - `vector_result_t vector_set(vector, index, value)`: update the value of a given index if it exists;
- `vector_result_t vector_get(vector, index)`: return the value indexed by `index` if it exists; - `vector_result_t vector_get(vector, index)`: return the value indexed by `index` if it exists;
- `map_result_t vector_sort(map, cmp)`: sort array using `cmp` function;
- `vector_result_t vector_pop(vector)`: pop last element from the vector following the LIFO policy; - `vector_result_t vector_pop(vector)`: pop last element from the vector following the LIFO policy;
- `vector_result_t vector_clear(vector)`: logically reset the vector. That is, new pushes - `vector_result_t vector_clear(vector)`: logically reset the vector. That is, new pushes
will overwrite the memory; will overwrite the memory;
@@ -241,6 +242,178 @@ Just like for the `Map` data structure, if the operation was successful
(that is, `status == VECTOR_OK`), you can either move on with the rest of the program (that is, `status == VECTOR_OK`), you can either move on with the rest of the program
or read the returned value from the sum data type. or read the returned value from the sum data type.
## Sorting
The `Vector` data structure provides an efficient in-place sorting method called `vector_sort`
which uses a builtin [Quicksort](https://en.wikipedia.org/wiki/Quicksort) implementation. This
function requires an user-defined comparison procedure as its second parameter, which allows
the caller to customize the sorting behavior. It must adhere to the following specification:
1. Must return `vector_order_t`, which is defined as follows:
```c
typedef enum {
VECTOR_ORDER_LT = 0x0, // First element should come before the second
VECTOR_ORDER_EQ, // The two elements are equivalent
VECTOR_ORDER_GT // First element should come after the second
} vector_order_t;
```
and indicates the ordering relationship between any two elements.
2. Must accept two `const void*` parameters representing the two elements to compare;
3. Must be self-contained and handle all its own resources.
Let's look at some examples; for instance, let's sort an integer array in ascending and
descending order:
```c
#include <stdio.h>
#include "src/vector.h"
vector_order_t cmp_int_asc(const void *x, const void *y) {
int x_int = *(const int*)x;
int y_int = *(const int*)y;
if (x_int < y_int) return VECTOR_ORDER_LT;
if (x_int > y_int) return VECTOR_ORDER_GT;
return VECTOR_ORDER_EQ;
}
vector_order_t cmp_int_desc(const void *x, const void *y) {
return cmp_int_asc(y, x);
}
/*
* Compile with: gcc main.c src/vector.h
* Output: Before sorting: -8 20 -10 125 34 9
* After sorting (ascending order): -10 -8 9 20 34 125
* After sorting (descending order): 125 34 20 9 -8 -10
*/
int main(void) {
vector_t *v = vector_new(5, sizeof(int)).value.vector;
int values[] = { -8, 20, -10, 125, 34, 9 };
for (size_t idx = 0; idx < 6; idx++) {
vector_push(v, &values[idx]);
}
// Print unsorted array
printf("Before sorting: ");
for (size_t idx = 0; idx < vector_size(v); idx++) {
printf("%d ", *(int*)vector_get(v, idx).value.element);
}
// Sort array in ascending order
vector_sort(v, cmp_int_asc);
// Print sorted array
printf("\nAfter sorting (ascending order): ");
for (size_t idx = 0; idx < vector_size(v); idx++) {
printf("%d ", *(int*)vector_get(v, idx).value.element);
}
// Sort array in descending order
vector_sort(v, cmp_int_desc);
// Print sorted array
printf("\nAfter sorting (descending order): ");
for (size_t idx = 0; idx < vector_size(v); idx++) {
printf("%d ", *(int*)vector_get(v, idx).value.element);
}
printf("\n");
vector_destroy(v);
return 0;
}
```
Obviously, you can use the `vector_sort` method on custom data types as well. For instance, let's suppose that you have a
struct representing employees and you want to sort them based on their age and based on their name (lexicographic sort):
```c
#include <stdio.h>
#include <string.h>
#include "src/vector.h"
typedef struct {
char name[256];
int age;
} Employee;
vector_order_t cmp_person_by_age(const void *x, const void *y) {
const Employee *x_person = (const Employee*)x;
const Employee *y_person = (const Employee*)y;
if (x_person->age < y_person->age) return VECTOR_ORDER_LT;
if (x_person->age > y_person->age) return VECTOR_ORDER_GT;
return VECTOR_ORDER_EQ;
}
vector_order_t cmp_person_by_name(const void *x, const void *y) {
const Employee *x_person = (const Employee*)x;
const Employee *y_person = (const Employee*)y;
const int result = strcmp(x_person->name, y_person->name);
if(result < 0) return VECTOR_ORDER_LT;
if(result > 0) return VECTOR_ORDER_GT;
return VECTOR_ORDER_EQ;
}
/*
* Compile with: gcc main.c src/vector.h
* Output: Sort by age:
* Name: Marco, Age: 25
* Name: Alice, Age: 28
* Name: Bob, Age: 45
*
* Sort by name:
* Name: Alice, Age: 28
* Name: Bob, Age: 45
* Name: Marco, Age: 25
*/
int main(void) {
vector_t *employees = vector_new(5, sizeof(Employee)).value.vector;
Employee e1 = { .name = "Bob", .age = 45 };
Employee e2 = { .name = "Alice", .age = 28 };
Employee e3 = { .name = "Marco", .age = 25 };
vector_push(employees, &e1);
vector_push(employees, &e2);
vector_push(employees, &e3);
// Sort array by age
vector_sort(employees, cmp_person_by_age);
// Print sorted array
printf("Sort by age:\n");
for (size_t idx = 0; idx < vector_size(employees); idx++) {
Employee *p = (Employee*)vector_get(employees, idx).value.element;
printf("Name: %s, Age: %d\n", p->name, p->age);
}
// Sort array by name
vector_sort(employees, cmp_person_by_name);
// Print sorted array
printf("\nSort by name:\n");
for (size_t idx = 0; idx < vector_size(employees); idx++) {
Employee *p = (Employee*)vector_get(employees, idx).value.element;
printf("Name: %s, Age: %d\n", p->name, p->age);
}
vector_destroy(employees);
return 0;
}
```
## Unit tests ## Unit tests
Datum provides some unit tests for both the `Vector` and the `Map` data types. To run them, you can issue the following commands: Datum provides some unit tests for both the `Vector` and the `Map` data types. To run them, you can issue the following commands:

View File

@@ -7,8 +7,11 @@
#include "vector.h" #include "vector.h"
// Internal method to increase vector size // Internal methods
static vector_result_t vector_resize(vector_t *vector); static vector_result_t vector_resize(vector_t *vector);
static void swap(void *x, void *y, size_t size);
static size_t partition(void *base, size_t low, size_t high, size_t size, vector_cmp_fn cmp);
static void quicksort(void *base, size_t low, size_t high, size_t size, vector_cmp_fn cmp);
/** /**
* vector_new * vector_new
@@ -37,7 +40,7 @@ vector_result_t vector_new(size_t size, size_t data_size) {
} }
// Initialize vector // Initialize vector
vector->count = 0; vector->size = 0;
vector->capacity = size; vector->capacity = size;
vector->data_size = data_size; vector->data_size = data_size;
vector->elements = calloc(size, data_size); vector->elements = calloc(size, data_size);
@@ -94,6 +97,73 @@ vector_result_t vector_resize(vector_t *vector) {
return result; return result;
} }
/**
* swap
* @x: first element
* @y: second element
*
* Swaps @x and @y
*/
void swap(void *x, void *y, size_t size) {
uint8_t temp[size];
memcpy(temp, x, size);
memcpy(x, y, size);
memcpy(y, temp, size);
}
/**
* partition
* @base: the array/partition
* @low: lower index
* @high: higher index
* @size: data size
* @cmp: comparison function
*
* Divides an array into two partitions
*
* Returns the pivot index
*/
size_t partition(void *base, size_t low, size_t high, size_t size, vector_cmp_fn cmp) {
uint8_t *arr = (uint8_t*)base;
void *pivot = arr + (high * size);
size_t i = low;
for (size_t j = low; j < high; j++) {
vector_order_t order = cmp(arr + (j * size), pivot);
if (order == VECTOR_ORDER_LT || order == VECTOR_ORDER_EQ) {
swap(arr + (i * size), arr + (j * size), size);
i++;
}
}
swap(arr + (i * size), arr + (high * size), size);
return i;
}
/**
* quicksort
* @base: the base array/partition
* @low: lower index
* @high: higher index
* @size: data size
* @cmp: comparision function
*
* Recursively sorts an array/partition using the Quicksort algorithm
*/
void quicksort(void *base, size_t low, size_t high, size_t size, vector_cmp_fn cmp) {
if (low < high) {
const size_t pivot = partition(base, low, high, size, cmp);
if (pivot > 0) {
quicksort(base, low, pivot - 1, size, cmp);
}
quicksort(base, pivot + 1, high, size, cmp);
}
}
/** /**
* vector_push * vector_push
* @vector: a non-null vector * @vector: a non-null vector
@@ -114,7 +184,7 @@ vector_result_t vector_push(vector_t *vector, void *value) {
} }
// Check whether vector has enough space available // Check whether vector has enough space available
if (vector->capacity == vector->count) { if (vector->capacity == vector->size) {
result = vector_resize(vector); result = vector_resize(vector);
if (result.status != VECTOR_OK) { if (result.status != VECTOR_OK) {
return result; return result;
@@ -122,7 +192,7 @@ vector_result_t vector_push(vector_t *vector, void *value) {
} }
// Calculate destination memory address // Calculate destination memory address
uint8_t *destination_addr = (uint8_t*)vector->elements + (vector->count * vector->data_size); uint8_t *destination_addr = (uint8_t*)vector->elements + (vector->size * vector->data_size);
// Append @value to the data structure according to its data type // Append @value to the data structure according to its data type
if (vector->data_size == sizeof(int)) { if (vector->data_size == sizeof(int)) {
@@ -138,7 +208,7 @@ vector_result_t vector_push(vector_t *vector, void *value) {
} }
// Increase elements count // Increase elements count
vector->count++; vector->size++;
result.status = VECTOR_OK; result.status = VECTOR_OK;
SET_MSG(result, "Value successfully added"); SET_MSG(result, "Value successfully added");
@@ -166,7 +236,7 @@ vector_result_t vector_set(vector_t *vector, size_t index, void *value) {
return result; return result;
} }
if (index >= vector->count) { if (index >= vector->size) {
result.status = VECTOR_ERR_OVERFLOW; result.status = VECTOR_ERR_OVERFLOW;
SET_MSG(result, "Index out of bounds"); SET_MSG(result, "Index out of bounds");
@@ -211,7 +281,7 @@ vector_result_t vector_get(vector_t *vector, size_t index) {
return result; return result;
} }
if (index >= vector->count) { if (index >= vector->size) {
result.status = VECTOR_ERR_OVERFLOW; result.status = VECTOR_ERR_OVERFLOW;
SET_MSG(result, "Index out of bounds"); SET_MSG(result, "Index out of bounds");
@@ -225,6 +295,48 @@ vector_result_t vector_get(vector_t *vector, size_t index) {
return result; return result;
} }
/**
* vector_sort
* @vector: a non-null vector
* @cmp: a user-defined comparison function returning vector_order_t
*
* Sorts @vector using Quicksort algorithm and the @cmp comparison function
*
* Returns a vecto_result_t data type
*/
vector_result_t vector_sort(vector_t *vector, vector_cmp_fn cmp) {
vector_result_t result = {0};
if (vector == NULL) {
result.status = VECTOR_ERR_INVALID;
SET_MSG(result, "Invalid vector");
return result;
}
if (cmp == NULL) {
result.status = VECTOR_ERR_INVALID;
SET_MSG(result, "Invalid comparison function");
return result;
}
// The vector is already sorted
if (vector->size <= 1) {
result.status = VECTOR_OK;
SET_MSG(result, "Vector successfully sorted");
return result;
}
quicksort(vector->elements, 0, vector->size - 1, vector->data_size, cmp);
result.status = VECTOR_OK;
SET_MSG(result, "Vector successfully sorted");
return result;
}
/** /**
* vector_pop * vector_pop
* @vector: a non-null vector * @vector: a non-null vector
@@ -244,7 +356,7 @@ vector_result_t vector_pop(vector_t *vector) {
return result; return result;
} }
if (vector->count == 0) { if (vector->size == 0) {
result.status = VECTOR_ERR_UNDERFLOW; result.status = VECTOR_ERR_UNDERFLOW;
SET_MSG(result, "Vector is empty"); SET_MSG(result, "Vector is empty");
@@ -252,14 +364,14 @@ vector_result_t vector_pop(vector_t *vector) {
} }
// Pop an element from the vector // Pop an element from the vector
const size_t index = (vector->count - 1); const size_t index = (vector->size - 1);
vector_result_t popped_res = vector_get(vector, index); vector_result_t popped_res = vector_get(vector, index);
if (popped_res.status != VECTOR_OK) { if (popped_res.status != VECTOR_OK) {
return popped_res; return popped_res;
} }
vector->count--; vector->size--;
result.status = VECTOR_OK; result.status = VECTOR_OK;
SET_MSG(result, "Value successfully popped"); SET_MSG(result, "Value successfully popped");
@@ -286,7 +398,7 @@ vector_result_t vector_clear(vector_t *vector) {
return result; return result;
} }
vector->count = 0; vector->size = 0;
result.status = VECTOR_OK; result.status = VECTOR_OK;
SET_MSG(result, "Vector successfully cleared"); SET_MSG(result, "Vector successfully cleared");

View File

@@ -15,7 +15,7 @@ typedef enum {
} vector_status_t; } vector_status_t;
typedef struct { typedef struct {
size_t count; size_t size;
size_t capacity; size_t capacity;
size_t data_size; size_t data_size;
void *elements; void *elements;
@@ -30,6 +30,14 @@ typedef struct {
} value; } value;
} vector_result_t; } vector_result_t;
typedef enum {
VECTOR_ORDER_LT = 0x0,
VECTOR_ORDER_EQ,
VECTOR_ORDER_GT
} vector_order_t;
typedef vector_order_t (*vector_cmp_fn)(const void *x, const void *y);
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@@ -39,13 +47,14 @@ vector_result_t vector_new(size_t size, size_t data_size);
vector_result_t vector_push(vector_t *vector, void *value); vector_result_t vector_push(vector_t *vector, void *value);
vector_result_t vector_set(vector_t *vector, size_t index, void *value); vector_result_t vector_set(vector_t *vector, size_t index, void *value);
vector_result_t vector_get(vector_t *vector, size_t index); vector_result_t vector_get(vector_t *vector, size_t index);
vector_result_t vector_sort(vector_t *vector, vector_cmp_fn cmp);
vector_result_t vector_pop(vector_t *vector); vector_result_t vector_pop(vector_t *vector);
vector_result_t vector_clear(vector_t *vector); vector_result_t vector_clear(vector_t *vector);
vector_result_t vector_destroy(vector_t *vector); vector_result_t vector_destroy(vector_t *vector);
// Inline methods // Inline methods
static inline size_t vector_size(const vector_t *vector) { static inline size_t vector_size(const vector_t *vector) {
return vector ? vector->count : 0; return vector ? vector->size : 0;
} }
static inline size_t vector_capacity(const vector_t *vector) { static inline size_t vector_capacity(const vector_t *vector) {

View File

@@ -104,6 +104,206 @@ void test_vector_get_ofb() {
vector_destroy(v); vector_destroy(v);
} }
// Sort integers in ascending order
vector_order_t cmp_int_asc(const void *x, const void *y) {
int x_int = *(const int*)x;
int y_int = *(const int*)y;
if (x_int < y_int) return VECTOR_ORDER_LT;
if (x_int > y_int) return VECTOR_ORDER_GT;
return VECTOR_ORDER_EQ;
}
vector_order_t cmp_int_desc(const void *x, const void *y) {
return cmp_int_asc(y, x);
}
void test_vector_sort_int_asc() {
vector_result_t res = vector_new(5, sizeof(int));
assert(res.status == VECTOR_OK);
vector_t *v = res.value.vector;
int values[] = { 25, 4, 12, -7, 25, 71, 1, 6 };
for (size_t idx = 0; idx < 8; idx++) {
vector_push(v, &values[idx]);
}
vector_result_t sort_res = vector_sort(v, cmp_int_asc);
assert(sort_res.status == VECTOR_OK);
const int expected[] = { -7, 1, 4, 6, 12, 25, 25, 71 };
for (size_t idx = 0; idx < vector_size(v); idx++) {
int *val = (int*)vector_get(v, idx).value.element;
assert(*val == expected[idx]);
}
vector_destroy(v);
}
void test_vector_sort_int_desc() {
vector_result_t res = vector_new(5, sizeof(int));
assert(res.status == VECTOR_OK);
vector_t *v = res.value.vector;
int values[] = { 25, 4, 12, -7, 25, 71, 1, 6 };
for (size_t idx = 0; idx < 8; idx++) {
vector_push(v, &values[idx]);
}
vector_result_t sort_res = vector_sort(v, cmp_int_desc);
assert(sort_res.status == VECTOR_OK);
const int expected[] = { 71, 25, 25, 12, 6, 4, 1, -7 };
for (size_t idx = 0; idx < vector_size(v); idx++) {
int *val = (int*)vector_get(v, idx).value.element;
assert(*val == expected[idx]);
}
vector_destroy(v);
}
// Sort strings in descending order
vector_order_t cmp_string_desc(const void *x, const void *y) {
const char *x_str = *(const char* const*)x;
const char *y_str = *(const char* const*)y;
// strcmp() returns an integer indicating the result of the comparison, as follows:
// - 0, if the s1 and s2 are equal;
// - a negative value if s1 is less than s2;
// - a positive value if s1 is greater than s2.
// for descending order, just invert the result
const int result = strcmp(x_str, y_str);
if (result < 0) return VECTOR_ORDER_GT;
if (result > 0) return VECTOR_ORDER_LT;
return VECTOR_ORDER_EQ;
}
void test_vector_sort_string() {
vector_result_t res = vector_new(5, sizeof(char*));
assert(res.status == VECTOR_OK);
vector_t *v = res.value.vector;
const char *values[] = { "embedded", "system-programming", "foo", "bar", "hello", "world!" };
for (size_t idx = 0; idx < 6; idx++) {
vector_push(v, &values[idx]);
}
vector_result_t sort_res = vector_sort(v, cmp_string_desc);
assert(sort_res.status == VECTOR_OK);
const char *expected[] = { "world!", "system-programming", "hello", "foo", "embedded", "bar"};
for (size_t idx = 0; idx < vector_size(v); idx++) {
const char *val = *(const char**)vector_get(v, idx).value.element;
assert(!strcmp(val, expected[idx]));
}
vector_destroy(v);
}
// Sort vector with custom data type
typedef struct {
char name[256];
int age;
} Person;
vector_order_t cmp_person_by_age(const void *x, const void *y) {
const Person *x_person = (const Person*)x;
const Person *y_person = (const Person*)y;
if (x_person->age < y_person->age) return VECTOR_ORDER_LT;
if (x_person->age > y_person->age) return VECTOR_ORDER_GT;
return VECTOR_ORDER_EQ;
}
vector_order_t cmp_person_by_name(const void *x, const void *y) {
const Person *x_person = (const Person*)x;
const Person *y_person = (const Person*)y;
const int result = strcmp(x_person->name, y_person->name);
if(result < 0) return VECTOR_ORDER_LT;
if(result > 0) return VECTOR_ORDER_GT;
return VECTOR_ORDER_EQ;
}
void test_vector_sort_struct_by_age() {
vector_result_t res = vector_new(5, sizeof(Person));
assert(res.status == VECTOR_OK);
vector_t *people = res.value.vector;
Person p1 = { .name = "Bob", .age = 45 };
Person p2 = { .name = "Alice", .age = 28 };
Person p3 = { .name = "Marco", .age = 25 };
vector_push(people, &p1);
vector_push(people, &p2);
vector_push(people, &p3);
vector_result_t sort_res = vector_sort(people, cmp_person_by_age);
assert(sort_res.status == VECTOR_OK);
Person expected[] = {
{ .name = "Marco", .age = 25 },
{ .name = "Alice", .age = 28 },
{ .name = "Bob", .age = 45 }
};
for (size_t idx = 0; idx < vector_size(people); idx++) {
Person *p = (Person*)vector_get(people, idx).value.element;
assert(!strcmp(p->name, expected[idx].name));
assert(p->age == expected[idx].age);
}
vector_destroy(people);
}
void test_vector_sort_struct_by_name() {
vector_result_t res = vector_new(5, sizeof(Person));
assert(res.status == VECTOR_OK);
vector_t *people = res.value.vector;
Person p1 = { .name = "Sophia", .age = 45 };
Person p2 = { .name = "Robert", .age = 28 };
Person p3 = { .name = "Barbara", .age = 25 };
Person p4 = { .name = "Christopher", .age = 65 };
Person p5 = { .name = "Paul", .age = 53 };
vector_push(people, &p1);
vector_push(people, &p2);
vector_push(people, &p3);
vector_push(people, &p4);
vector_push(people, &p5);
vector_result_t sort_res = vector_sort(people, cmp_person_by_name);
assert(sort_res.status == VECTOR_OK);
Person expected[] = {
{ .name = "Barbara", .age = 25 },
{ .name = "Christopher", .age = 65 },
{ .name = "Paul", .age = 53 },
{ .name = "Robert", .age = 28 },
{ .name = "Sophia", .age = 45 }
};
for (size_t idx = 0; idx < vector_size(people); idx++) {
Person *p = (Person*)vector_get(people, idx).value.element;
assert(!strcmp(p->name, expected[idx].name));
assert(p->age == expected[idx].age);
}
vector_destroy(people);
}
// Set vector element // Set vector element
void test_vector_set() { void test_vector_set() {
vector_result_t res = vector_new(5, sizeof(int)); vector_result_t res = vector_new(5, sizeof(int));
@@ -123,7 +323,7 @@ void test_vector_set() {
vector_destroy(v); vector_destroy(v);
} }
// Set vector elemement out of bounds // Set vector element out of bounds
void test_vector_set_ofb() { void test_vector_set_ofb() {
vector_result_t res = vector_new(5, sizeof(int)); vector_result_t res = vector_new(5, sizeof(int));
@@ -278,6 +478,11 @@ int main(void) {
TEST(vector_push_realloc); TEST(vector_push_realloc);
TEST(vector_get); TEST(vector_get);
TEST(vector_get_ofb); TEST(vector_get_ofb);
TEST(vector_sort_int_asc);
TEST(vector_sort_int_desc);
TEST(vector_sort_string);
TEST(vector_sort_struct_by_age);
TEST(vector_sort_struct_by_name);
TEST(vector_set); TEST(vector_set);
TEST(vector_set_ofb); TEST(vector_set_ofb);
TEST(vector_pop); TEST(vector_pop);

85
usage.c
View File

@@ -23,6 +23,7 @@
static int vector_usage(); static int vector_usage();
static int map_usage(); static int map_usage();
static vector_order_t cmp_int_asc(const void *x, const void *y);
int main(void) { int main(void) {
int st; int st;
@@ -38,6 +39,20 @@ int main(void) {
return 0; return 0;
} }
vector_order_t cmp_int_asc(const void *x, const void *y) {
int x_int = *(const int*)x;
int y_int = *(const int*)y;
if (x_int < y_int) return VECTOR_ORDER_LT;
if (x_int > y_int) return VECTOR_ORDER_GT;
return VECTOR_ORDER_EQ;
}
vector_order_t cmp_int_desc(const void *x, const void *y) {
return cmp_int_asc(y, x);
}
int vector_usage() { int vector_usage() {
// Create a vector of 5 integers // Create a vector of 5 integers
vector_result_t res = vector_new(5, sizeof(int)); vector_result_t res = vector_new(5, sizeof(int));
@@ -100,10 +115,80 @@ int vector_usage() {
printf("Vector cleared (size should be 0): %zu\n\n", vector_size(vector)); printf("Vector cleared (size should be 0): %zu\n\n", vector_size(vector));
} }
// Sort vector in ascending order
int values[] = {5, 10, -9, 3, 1, 0, 4};
for (size_t idx = 0; idx < 7; idx++) {
vector_result_t sort_push_res = vector_push(vector, &values[idx]);
if (sort_push_res.status != VECTOR_OK) {
printf("Error while adding elements: %s\n", sort_push_res.message);
return 1;
}
}
printf("Added new elements. Before sort: ");
for (size_t idx = 0; idx < vector_size(vector); idx++) {
vector_result_t sort_get_res = vector_get(vector, idx);
if (sort_get_res.status != VECTOR_OK) {
printf("Cannot retrieve vec[%zu]: %s\n", idx, sort_get_res.message);
return 1;
} else {
const int *val = (int*)sort_get_res.value.element;
printf("%d ", *val);
}
}
printf("\n");
vector_result_t sort_asc_res = vector_sort(vector, cmp_int_asc);
if (sort_asc_res.status != VECTOR_OK) {
printf("Cannot sort array: %s\n", sort_asc_res.message);
return 1;
}
printf("After sort in ascending order: ");
for (size_t idx = 0; idx < vector_size(vector); idx++) {
vector_result_t sort_get_res = vector_get(vector, idx);
if (sort_get_res.status != VECTOR_OK) {
printf("Cannot retrieve vec[%zu]: %s\n", idx, sort_get_res.message);
return 1;
} else {
int *val = (int*)sort_get_res.value.element;
printf("%d ", *val);
}
}
printf("\n");
// Sort vector in descending order
vector_result_t sort_desc_res = vector_sort(vector, cmp_int_desc);
if (sort_desc_res.status != VECTOR_OK) {
printf("Cannot sort array: %s\n", sort_desc_res.message);
return 1;
}
printf("After sort in descending order: ");
for (size_t idx = 0; idx < vector_size(vector); idx++) {
vector_result_t sort_get_res = vector_get(vector, idx);
if (sort_get_res.status != VECTOR_OK) {
printf("Cannot retrieve vec[%zu]: %s\n", idx, sort_get_res.message);
return 1;
} else {
int *val = (int*)sort_get_res.value.element;
printf("%d ", *val);
}
}
printf("\n\n");
// Free vector // Free vector
vector_result_t del_res = vector_destroy(vector); vector_result_t del_res = vector_destroy(vector);
if (del_res.status != VECTOR_OK) { if (del_res.status != VECTOR_OK) {
printf("Error while destroying the vector: %s\n", del_res.message); printf("Error while destroying the vector: %s\n", del_res.message);
return 1;
} }
return 0; return 0;