Skip to content

Commit e05b8e9

Browse files
committed
Implement MISRA compliant quick sort
- MISRA compliant quick sort
1 parent b903c82 commit e05b8e9

File tree

6 files changed

+203
-0
lines changed

6 files changed

+203
-0
lines changed

Inc/sort/quick_sort.h

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/****************************************************************************
2+
*
3+
* Copyright (c) 2025 IMProject Development Team. All rights reserved.
4+
* Authors: Juraj Ciberlin <[email protected]>
5+
*
6+
* Redistribution and use in source and binary forms, with or without
7+
* modification, are permitted provided that the following conditions
8+
* are met:
9+
*
10+
* 1. Redistributions of source code must retain the above copyright
11+
* notice, this list of conditions and the following disclaimer.
12+
* 2. Redistributions in binary form must reproduce the above copyright
13+
* notice, this list of conditions and the following disclaimer in
14+
* the documentation and/or other materials provided with the
15+
* distribution.
16+
* 3. Neither the name IMProject nor the names of its contributors may be
17+
* used to endorse or promote products derived from this software
18+
* without specific prior written permission.
19+
*
20+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22+
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23+
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24+
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25+
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26+
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27+
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28+
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29+
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30+
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31+
* POSSIBILITY OF SUCH DAMAGE.
32+
*
33+
****************************************************************************/
34+
35+
#ifndef UTILITY_QUICK_SORT_H_
36+
#define UTILITY_QUICK_SORT_H_
37+
38+
#include "typedefs.h"
39+
40+
#define MAX_NUM_OF_ELEMENTS (64)
41+
42+
/**
43+
* @brief Sort elements using quick sort algorithm. Quick sort algorithm works on divide and conquer
44+
* principle. Firstly, it selects an element from an array as a pivot. Secondly, partitioning is done
45+
* (array is arranged around the pivot). Elements smaller than the pivot will be on the left side,
46+
* elements that are greater than the pivot will be on the right side. Pivot will be in the correct
47+
* position. Repeat the process until the initial array is not sorted. This algorithm does not use
48+
* recursion since it is not MISRA compliant.
49+
* Time complexity: O(N log N)
50+
*
51+
* @param[in/out] *buffer Pointer to the buffer that contains elements that will be sorted.
52+
* @param[in] number_of_elements Number of elements in the buffer.
53+
* @param[in] element_size Size of the element, in bytes.
54+
* @param[in] *compareFun Pointer to compare function. Compare function has two parameters (pointer to
55+
* first element and pointer to second element). As a result, it returns boolean,
56+
* true if first element is greater than second element, otherwise false.
57+
*/
58+
void QuickSort_sort(byte_t* buffer, int32_t number_of_elements, int32_t element_size,
59+
bool (*compareFun)(void* first, void* second));
60+
61+
#endif /* UTILITY_QUICK_SORT_H_ */

Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ IMUTILITY_FILES=\
112112
Src/sort/heap_sort.c \
113113
Src/sort/insertion_sort.c \
114114
Src/sort/merge_sort.c \
115+
Src/sort/quick_sort.c \
115116
Src/sort/selection_sort.c \
116117
Src/json.c \
117118
Src/map.c \
@@ -140,6 +141,7 @@ SRC_FILES+=$(IMUTILITY_FILES) \
140141
Tests/test_merge_sort.c \
141142
Tests/test_priority_queue.c \
142143
Tests/test_queue.c \
144+
Tests/test_quick_sort.c \
143145
Tests/test_scheduler.c \
144146
Tests/test_selection_sort.c \
145147
Tests/test_utils.c \

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ Join us on the Discord channel https://discord.gg/R6nZxZqDH3
151151
- HeapSort_sort
152152
- InsertionSort_sort
153153
- MergeSort_sort
154+
- QuickSort_sort
154155
- SelectionSort_sort
155156

156157
### Utils

Src/sort/quick_sort.c

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/****************************************************************************
2+
*
3+
* Copyright (c) 2025 IMProject Development Team. All rights reserved.
4+
* Authors: Juraj Ciberlin <[email protected]>
5+
*
6+
* Redistribution and use in source and binary forms, with or without
7+
* modification, are permitted provided that the following conditions
8+
* are met:
9+
*
10+
* 1. Redistributions of source code must retain the above copyright
11+
* notice, this list of conditions and the following disclaimer.
12+
* 2. Redistributions in binary form must reproduce the above copyright
13+
* notice, this list of conditions and the following disclaimer in
14+
* the documentation and/or other materials provided with the
15+
* distribution.
16+
* 3. Neither the name IMProject nor the names of its contributors may be
17+
* used to endorse or promote products derived from this software
18+
* without specific prior written permission.
19+
*
20+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22+
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23+
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24+
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25+
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26+
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27+
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28+
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29+
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30+
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31+
* POSSIBILITY OF SUCH DAMAGE.
32+
*
33+
****************************************************************************/
34+
35+
#include "quick_sort.h"
36+
37+
#include "utils.h"
38+
39+
static int32_t
40+
Partition(byte_t* buffer, int32_t start_index, int32_t end_index, int32_t element_size, bool (*compareFun)(void* first,
41+
void* second)) {
42+
int32_t pivot_pos = start_index - 1;
43+
44+
for (int32_t i = start_index; i <= (end_index - 1); ++i) {
45+
bool compare = compareFun(&buffer[end_index * element_size], &buffer[i * element_size]);
46+
if (compare) {
47+
++pivot_pos;
48+
Utils_swapElements(&buffer[pivot_pos * element_size], &buffer[i * element_size], (uint32_t)element_size);
49+
}
50+
}
51+
Utils_swapElements(&buffer[(pivot_pos + 1) * element_size], &buffer[end_index * element_size], (uint32_t)element_size);
52+
++pivot_pos;
53+
return pivot_pos;
54+
}
55+
56+
void
57+
QuickSort_sort(byte_t* buffer, int32_t number_of_elements, int32_t element_size,
58+
bool (*compareFun)(void* first, void* second)) {
59+
int32_t indexes[MAX_NUM_OF_ELEMENTS] = {0, number_of_elements - 1};
60+
61+
int32_t top = 1;
62+
63+
while (top >= 0) {
64+
int32_t end_index = indexes[top];
65+
--top;
66+
int32_t start_index = indexes[top];
67+
--top;
68+
69+
int32_t pivot_index = Partition(buffer, start_index, end_index, element_size, compareFun);
70+
71+
if ((pivot_index - 1) > start_index) {
72+
++top;
73+
indexes[top] = start_index;
74+
++top;
75+
indexes[top] = pivot_index - 1;
76+
}
77+
78+
if ((pivot_index + 1) < end_index) {
79+
++top;
80+
indexes[top] = pivot_index + 1;
81+
++top;
82+
indexes[top] = end_index;
83+
}
84+
}
85+
}

Tests/test_main.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ RunAllTests(void) {
1818
RUN_TEST_GROUP(MergeSort);
1919
RUN_TEST_GROUP(PriorityQueue);
2020
RUN_TEST_GROUP(Queue);
21+
RUN_TEST_GROUP(QuickSort);
2122
RUN_TEST_GROUP(Scheduler);
2223
RUN_TEST_GROUP(SelectionSort);
2324
RUN_TEST_GROUP(Utils);

Tests/test_quick_sort.c

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#include "quick_sort.h"
2+
3+
#include "unity.h"
4+
#include "unity_fixture.h"
5+
6+
#include "helper/sort_functions.h"
7+
8+
TEST_GROUP(QuickSort);
9+
10+
TEST_SETUP(QuickSort) {
11+
}
12+
13+
TEST_TEAR_DOWN(QuickSort) {
14+
}
15+
16+
TEST_GROUP_RUNNER(QuickSort) {
17+
RUN_TEST_CASE(QuickSort, QuickSort_int32);
18+
RUN_TEST_CASE(QuickSort, QuickSort_float64);
19+
RUN_TEST_CASE(QuickSort, QuickSort_uint64);
20+
}
21+
22+
TEST(QuickSort, QuickSort_int32) {
23+
int32_t unsorted_array[] = {5, 2, 3, 1000000, 9, 10, 11, 8, 9, 100};
24+
const int32_t sorted_array[] = {2, 3, 5, 8, 9, 9, 10, 11, 100, 1000000};
25+
QuickSort_sort((byte_t*)unsorted_array, sizeof(unsorted_array) / sizeof(unsorted_array[0]), sizeof(unsorted_array[0]),
26+
CompareInt32);
27+
28+
for (uint32_t i = 0U; i < (sizeof(unsorted_array) / sizeof(unsorted_array[0])); ++i) {
29+
TEST_ASSERT_EQUAL_INT32(sorted_array[i], unsorted_array[i]);
30+
}
31+
}
32+
33+
TEST(QuickSort, QuickSort_float64) {
34+
float64_t unsorted_array[] = {5.8, 2.2, 3.1, 1.1, 9.1, 10.3, 11.2, 8.4, 9.2, 100.9};
35+
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};
36+
QuickSort_sort((byte_t*)unsorted_array, sizeof(unsorted_array) / sizeof(unsorted_array[0]), sizeof(unsorted_array[0]),
37+
CompareFloat64);
38+
39+
for (uint32_t i = 0U; i < (sizeof(unsorted_array) / sizeof(unsorted_array[0])); ++i) {
40+
TEST_ASSERT_EQUAL_DOUBLE(sorted_array[i], unsorted_array[i]);
41+
}
42+
}
43+
44+
TEST(QuickSort, QuickSort_uint64) {
45+
uint64_t unsorted_array[] = {1111111U, 55555555U, 44444U, 10000000000000U, 212121U, 1111U, 1U, 2U, 5U, 3U};
46+
const uint64_t sorted_array[] = {1U, 2U, 3U, 5U, 1111U, 44444U, 212121U, 1111111U, 55555555U, 10000000000000U};
47+
QuickSort_sort((byte_t*)unsorted_array, sizeof(unsorted_array) / sizeof(unsorted_array[0]), sizeof(unsorted_array[0]),
48+
CompareUint64);
49+
50+
for (uint32_t i = 0U; i < (sizeof(unsorted_array) / sizeof(unsorted_array[0])); ++i) {
51+
TEST_ASSERT_EQUAL_UINT64(sorted_array[i], unsorted_array[i]);
52+
}
53+
}

0 commit comments

Comments
 (0)