Skip to content

Commit

Permalink
Implement MISRA compliant selection sort
Browse files Browse the repository at this point in the history
- MISRA compliant selection sort
  • Loading branch information
jciberlin authored and Igor-Misic committed Dec 28, 2023
1 parent 6c66b3a commit b3b2fd5
Show file tree
Hide file tree
Showing 10 changed files with 187 additions and 8 deletions.
2 changes: 1 addition & 1 deletion 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/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 <jciberlin1@gmail.com>
*
* 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_ */
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ IMUTILITY_FILES=\
Src/crc/crc32_variants/crc32_xfer.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 @@ -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
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,9 @@ Join us on the Discord channel https://discord.gg/R6nZxZqDH3
- Scheduler_addTask
- Scheduler_run

### Selection sort
- SelectionSort_sort

### Utils
- Utils_StringToUint32
- Utils_swapElements
Expand Down
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 <jciberlin1@gmail.com>
*
* 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);
}
}
}
6 changes: 3 additions & 3 deletions Tests/test_bubble_sort.c
Original file line number Diff line number Diff line change
Expand Up @@ -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]);
}
}
6 changes: 3 additions & 3 deletions Tests/test_heap_sort.c
Original file line number Diff line number Diff line change
Expand Up @@ -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]);
}
}

0 comments on commit b3b2fd5

Please sign in to comment.