Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Selection sort algorithm #67

Merged
merged 3 commits into from
Dec 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Inc/bubble_sort.h → Inc/sort/bubble_sort.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
/**
* @brief Sort elements using bubble sort algorithm.
*
* @param[in, out] *buffer Pointer to the buffer that contains elements that will be sorted.
* @param[in/out] *buffer Pointer to the buffer that contains elements that will be sorted.
* @param[in] number_of_elements Number of elements in the buffer.
* @param[in] element_size Size of the element, in bytes.
* @param[in] *compareFun Pointer to compare function. Compare function has two parameters (pointer to
Expand Down
2 changes: 1 addition & 1 deletion Inc/heap_sort.h → Inc/sort/heap_sort.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
/**
* @brief Sort elements using heap sort algorithm.
*
* @param[in, out] *buffer Pointer to the buffer that contains elements that will be sorted.
* @param[in/out] *buffer Pointer to the buffer that contains elements that will be sorted.
* @param[in] number_of_elements Number of elements in the buffer.
* @param[in] element_size Size of the element, in bytes.
* @param[in] *compareFun Pointer to compare function. Compare function has two parameters (pointer to
Expand Down
59 changes: 59 additions & 0 deletions Inc/sort/selection_sort.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/****************************************************************************
*
* Copyright (c) 2023 IMProject Development Team. All rights reserved.
* Authors: Juraj Ciberlin <[email protected]>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name IMProject nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/

#ifndef UTILITY_SELECTION_SORT_H_
#define UTILITY_SELECTION_SORT_H_

#include "typedefs.h"

/**
* @brief Sort elements using selection sort algorithm. Selection sort algorithm is an in-place
* comparison sorting algorithm that has O(n2) time complexity. It divides the input array into
* two parts, sorted sub-array of items which is built up from left to right and unsorted items
* that occupies the rest of the array. The sorted sub-array is empty and the unsorted sub-array
* is the entire input array. The algorithm proceeds by finding the smallest element in the
* unsorted sub-array, swapping it with the leftmost unsorted element (putting it in sorted order),
* and moving the sub-array boundaries one element to the right.
*
* @param[in/out] *buffer Pointer to the buffer that contains elements that will be sorted.
* @param[in] number_of_elements Number of elements in the buffer.
* @param[in] element_size Size of the element, in bytes.
* @param[in] *compareFun Pointer to compare function. Compare function has two parameters (pointer to
* first element and pointer to second element). As a result, it returns boolean,
* true if first element is greater than second element, otherwise false.
*/
void SelectionSort_sort(byte_t* buffer, uint32_t number_of_elements, uint32_t element_size,
bool (*compareFun)(void* first, void* second));

#endif /* UTILITY_SELECTION_SORT_H_ */
6 changes: 3 additions & 3 deletions Inc/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,13 @@
bool Utils_StringToUint32(const char* str, uint8_t str_length, uint32_t* integer);

/**
* @brief Swaps the contents of two byte arrays of the same size.
* @brief Swap two elements. Swap the content of two byte arrays of the same size.
*
* @param first[in/out] Pointer to the first array.
* @param second[in/out] Pointer to the second array.
* @param size[in] The number of bytes in each array.
* @param size[in] Size of the element. The number of bytes in each array.
*/
void Utils_SwapElements(byte_t* first, byte_t* second, uint32_t size);
void Utils_swapElements(byte_t* first, byte_t* second, uint32_t size);

/**
* @brief Quickly calculates 10 raised to the power of the given exponent
Expand Down
8 changes: 5 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ TARGET = $(TARGET_DIR)/$(TARGET_BASE)$(TARGET_EXTENSION)
IMUTILITY_FILES=\
Src/base64.c \
Src/bit_manipulation.c \
Src/bubble_sort.c \
Src/crc/crc8_base.c \
Src/crc/crc8_variants/crc8.c \
Src/crc/crc8_variants/crc8_8h2f.c \
Expand Down Expand Up @@ -106,7 +105,9 @@ IMUTILITY_FILES=\
Src/crc/crc32_variants/crc32_posix.c \
Src/crc/crc32_variants/crc32_q.c \
Src/crc/crc32_variants/crc32_xfer.c \
Src/heap_sort.c \
Src/sort/bubble_sort.c \
Src/sort/heap_sort.c \
Src/sort/selection_sort.c \
Src/json.c \
Src/map.c \
Src/priority_queue.c \
Expand All @@ -117,7 +118,7 @@ IMUTILITY_FILES=\
SRC_FILES+=$(IMUTILITY_FILES) \
$(UNITY_ROOT)/src/unity.c \
$(UNITY_ROOT)/extras/fixture/src/unity_fixture.c \
Tests/Helper/sort_functions.c \
Tests/helper/sort_functions.c \
Tests/test_main.c \
Tests/test_base64.c \
Tests/test_bit_manipulation.c \
Expand All @@ -131,6 +132,7 @@ SRC_FILES+=$(IMUTILITY_FILES) \
Tests/test_priority_queue.c \
Tests/test_queue.c \
Tests/test_scheduler.c \
Tests/test_selection_sort.c \
Tests/test_utils.c
INC_DIRS_CODE=-IInc -IInc/crc -IInc/crc/crc8_variants -IInc/crc/crc16_variants -IInc/crc/crc32_variants
INC_DIRS=$(INC_DIRS_CODE) -I$(UNITY_ROOT)/src -I$(UNITY_ROOT)/extras/fixture/src
Expand Down
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,12 @@ Join us on the Discord channel https://discord.gg/R6nZxZqDH3
- Scheduler_addTask
- Scheduler_run

### Selection sort
- SelectionSort_sort

### Utils
- Utils_StringToUint32
- Utils_SwapElements
- Utils_swapElements
- Utils_QuickUint32Pow10
- Utils_Serialize8
- Utils_Deserialize8
Expand Down
4 changes: 2 additions & 2 deletions Src/bubble_sort.c → Src/sort/bubble_sort.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
*
****************************************************************************/

#include "bubble_sort.h"
#include "sort/bubble_sort.h"

#include "utils.h"

Expand All @@ -46,7 +46,7 @@ BubbleSort_sort(byte_t* buffer, int32_t number_of_elements, uint32_t element_siz
swapped = false;
for (int32_t j = 0; j < (number_of_elements - i - 1); ++j) {
if (compareFun(&elements[j * (int32_t)element_size], &elements[(j + 1) * (int32_t)element_size])) {
Utils_SwapElements(&elements[j * (int32_t)element_size], &elements[(j + 1) * (int32_t)element_size], element_size);
Utils_swapElements(&elements[j * (int32_t)element_size], &elements[(j + 1) * (int32_t)element_size], element_size);
swapped = true;
}
}
Expand Down
6 changes: 3 additions & 3 deletions Src/heap_sort.c → Src/sort/heap_sort.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
*
****************************************************************************/

#include "heap_sort.h"
#include "sort/heap_sort.h"

#include "utils.h"

Expand Down Expand Up @@ -62,7 +62,7 @@ Heapify(byte_t* buffer, int32_t n, int32_t i, uint32_t element_size,
}

if (largest != index) {
Utils_SwapElements(&elements[index * (int32_t)element_size], &elements[largest * (int32_t)element_size], element_size);
Utils_swapElements(&elements[index * (int32_t)element_size], &elements[largest * (int32_t)element_size], element_size);
index = largest;
} else {
continue_iterating = false;
Expand All @@ -80,7 +80,7 @@ HeapSort_sort(byte_t* buffer, int32_t number_of_elements, uint32_t element_size,
}

for (i = number_of_elements - 1; i >= 0; --i) {
Utils_SwapElements(&elements[0], &elements[i * (int32_t)element_size], element_size);
Utils_swapElements(&elements[0], &elements[i * (int32_t)element_size], element_size);
Heapify(elements, i, 0, element_size, compareFun);
}
}
58 changes: 58 additions & 0 deletions Src/sort/selection_sort.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/****************************************************************************
*
* Copyright (c) 2023 IMProject Development Team. All rights reserved.
* Authors: Juraj Ciberlin <[email protected]>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name IMProject nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/

#include "sort/selection_sort.h"

#include "utils.h"

void
SelectionSort_sort(byte_t* buffer, uint32_t number_of_elements, uint32_t element_size,
bool (*compareFun)(void* first, void* second)) {
byte_t* elements = buffer;
uint32_t i;
uint32_t j;

for (i = 0U; i < (number_of_elements - 1U); ++i) {
uint32_t min_index = i;
for (j = i + 1U; j < number_of_elements; ++j) {
if (compareFun(&elements[min_index * element_size], &elements[j * element_size])) {
min_index = j;
}
}

if (min_index != i) {
Utils_swapElements(&elements[min_index * element_size], &elements[i * element_size], element_size);
}
}
}
2 changes: 1 addition & 1 deletion Src/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ Utils_StringToUint32(const char* str, uint8_t str_length, uint32_t* integer) {
}

void
Utils_SwapElements(byte_t* first, byte_t* second, uint32_t size) {
Utils_swapElements(byte_t* first, byte_t* second, uint32_t size) {
byte_t* first_element = first;
byte_t* second_element = second;
uint32_t index = size;
Expand Down
File renamed without changes.
File renamed without changes.
10 changes: 5 additions & 5 deletions Tests/test_bubble_sort.c
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#include "bubble_sort.h"
#include "sort/bubble_sort.h"

#include "unity.h"
#include "unity_fixture.h"

#include "Helper/sort_functions.h"
#include "helper/sort_functions.h"

TEST_GROUP(BubbleSort);

Expand All @@ -26,7 +26,7 @@ TEST(BubbleSort, BubbleSort_int32) {
CompareInt32);

for (uint32_t i = 0U; i < (sizeof(unsorted_array) / sizeof(unsorted_array[0])); ++i) {
TEST_ASSERT_EQUAL_INT32(unsorted_array[i], sorted_array[i]);
TEST_ASSERT_EQUAL_INT32(sorted_array[i], unsorted_array[i]);
}
}

Expand All @@ -37,7 +37,7 @@ TEST(BubbleSort, BubbleSort_float64) {
CompareFloat64);

for (uint32_t i = 0U; i < (sizeof(unsorted_array) / sizeof(unsorted_array[0])); ++i) {
TEST_ASSERT_EQUAL_DOUBLE(unsorted_array[i], sorted_array[i]);
TEST_ASSERT_EQUAL_DOUBLE(sorted_array[i], unsorted_array[i]);
}
}

Expand All @@ -48,6 +48,6 @@ TEST(BubbleSort, BubbleSort_uint64) {
CompareUint64);

for (uint32_t i = 0U; i < (sizeof(unsorted_array) / sizeof(unsorted_array[0])); ++i) {
TEST_ASSERT_EQUAL_UINT64(unsorted_array[i], sorted_array[i]);
TEST_ASSERT_EQUAL_UINT64(sorted_array[i], unsorted_array[i]);
}
}
10 changes: 5 additions & 5 deletions Tests/test_heap_sort.c
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#include "heap_sort.h"
#include "sort/heap_sort.h"

#include "unity.h"
#include "unity_fixture.h"

#include "Helper/sort_functions.h"
#include "helper/sort_functions.h"

TEST_GROUP(HeapSort);

Expand All @@ -26,7 +26,7 @@ TEST(HeapSort, HeapSort_int32) {
CompareInt32);

for (uint32_t i = 0U; i < (sizeof(unsorted_array) / sizeof(unsorted_array[0])); ++i) {
TEST_ASSERT_EQUAL_INT32(unsorted_array[i], sorted_array[i]);
TEST_ASSERT_EQUAL_INT32(sorted_array[i], unsorted_array[i]);
}
}

Expand All @@ -37,7 +37,7 @@ TEST(HeapSort, HeapSort_float64) {
CompareFloat64);

for (uint32_t i = 0U; i < (sizeof(unsorted_array) / sizeof(unsorted_array[0])); ++i) {
TEST_ASSERT_EQUAL_DOUBLE(unsorted_array[i], sorted_array[i]);
TEST_ASSERT_EQUAL_DOUBLE(sorted_array[i], unsorted_array[i]);
}
}

Expand All @@ -48,6 +48,6 @@ TEST(HeapSort, HeapSort_uint64) {
CompareUint64);

for (uint32_t i = 0U; i < (sizeof(unsorted_array) / sizeof(unsorted_array[0])); ++i) {
TEST_ASSERT_EQUAL_UINT64(unsorted_array[i], sorted_array[i]);
TEST_ASSERT_EQUAL_UINT64(sorted_array[i], unsorted_array[i]);
}
}
1 change: 1 addition & 0 deletions Tests/test_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ RunAllTests(void) {
RUN_TEST_GROUP(PriorityQueue);
RUN_TEST_GROUP(Queue);
RUN_TEST_GROUP(Scheduler);
RUN_TEST_GROUP(SelectionSort);
RUN_TEST_GROUP(Utils);
}

Expand Down
56 changes: 56 additions & 0 deletions Tests/test_selection_sort.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#include "sort/selection_sort.h"

#include "unity.h"
#include "unity_fixture.h"

#include "helper/sort_functions.h"

TEST_GROUP(SelectionSort);

TEST_SETUP(SelectionSort) {
}

TEST_TEAR_DOWN(SelectionSort) {
}

TEST_GROUP_RUNNER(SelectionSort) {
RUN_TEST_CASE(SelectionSort, SelectionSort_int32);
RUN_TEST_CASE(SelectionSort, SelectionSort_float64);
RUN_TEST_CASE(SelectionSort, SelectionSort_uint64);
}

TEST(SelectionSort, SelectionSort_int32) {
int32_t unsorted_array[] = {5, 2, 3, 1000000, 9, 10, 11, 8, 9, 100};
const int32_t sorted_array[] = {2, 3, 5, 8, 9, 9, 10, 11, 100, 1000000};
SelectionSort_sort((byte_t*)unsorted_array, sizeof(unsorted_array) / sizeof(unsorted_array[0]),
sizeof(unsorted_array[0]),
CompareInt32);

for (uint32_t i = 0U; i < (sizeof(unsorted_array) / sizeof(unsorted_array[0])); ++i) {
TEST_ASSERT_EQUAL_INT32(sorted_array[i], unsorted_array[i]);
}
}

TEST(SelectionSort, SelectionSort_float64) {
float64_t unsorted_array[] = {5.8, 2.2, 3.1, 1.1, 9.1, 10.3, 11.2, 8.4, 9.2, 100.9};
const float64_t sorted_array[] = {1.1, 2.2, 3.1, 5.8, 8.4, 9.1, 9.2, 10.3, 11.2, 100.9};
SelectionSort_sort((byte_t*)unsorted_array, sizeof(unsorted_array) / sizeof(unsorted_array[0]),
sizeof(unsorted_array[0]),
CompareFloat64);

for (uint32_t i = 0U; i < (sizeof(unsorted_array) / sizeof(unsorted_array[0])); ++i) {
TEST_ASSERT_EQUAL_DOUBLE(sorted_array[i], unsorted_array[i]);
}
}

TEST(SelectionSort, SelectionSort_uint64) {
uint64_t unsorted_array[] = {1111111U, 55555555U, 44444U, 10000000000000U, 212121U, 1111U, 1U, 2U, 5U, 3U};
const uint64_t sorted_array[] = {1U, 2U, 3U, 5U, 1111U, 44444U, 212121U, 1111111U, 55555555U, 10000000000000U};
SelectionSort_sort((byte_t*)unsorted_array, sizeof(unsorted_array) / sizeof(unsorted_array[0]),
sizeof(unsorted_array[0]),
CompareUint64);

for (uint32_t i = 0U; i < (sizeof(unsorted_array) / sizeof(unsorted_array[0])); ++i) {
TEST_ASSERT_EQUAL_UINT64(sorted_array[i], unsorted_array[i]);
}
}
Loading