I am looking for a suitable algorithm to build a relatively small (up to 255 elements) sorted array of integers. The target platform is a STM32 based embedded system. Since memory is limited, an in-place method is preferred.
I am aware that the obvious way is implement and profile the usual suspects (quick sort, insert sert, shell sort), but would like to ask for your experiences nevertheless. More specifically I have found very little information on the performance when building the array - that is, how well different algorithms may use the fact that all existing elements are already ordered.
Edit 1: Although the question is tagged C++ the STL is not available. Furthermore, the sorting does indeed occur inside a inner loop. To further clarify, I am looking for an algorithm that is especially suited to build a sorted list in an efficient manner. I assume (maybe wrongly) there must be algorithms specially suited for this task. That's the question.
Edit 2: When saying building a sorted list I mean that the list starts empty and is filled by by a bounded number (max 255) of 16-bit integers which are in no particular order. The list must be processed after all elements have been stored. For processing the list must be sorted, preferably in descending order.
Thanks in advance, Arne
Insertion Sort works best with small number of elements. The worst case runtime complexity of Insertion Sort is O ( n 2 ) O(n^2) O(n2) similar to that of Bubble Sort. However, Insertion Sort is considered better than Bubble sort.
Insertion sort is a simple sorting algorithm that works similar to the way you sort playing cards in your hands. The array is virtually split into a sorted and an unsorted part. Values from the unsorted part are picked and placed at the correct position in the sorted part.
Since we're talking about a Sorted Linked List, and you're inserting without knowing where an element is supposed to go, it will take you O(n) time (since you have to search the whole list to find the place the element goes).
Insertion sort requires n – 1 pass to sort an array of n elements. In each pass we insert the current element at the appropriate place so that the elements in the current range is in order.
If your problem demands that:
then you've painted yourself into a corner: your requirements spell "insertion sort".
No matter what algorithm or auxiliary datastructure you choose, inserting a new element in the middle will require you to move the larger elements up by an index, and deleting any element (except the largest) will require you to move the larger elements down by an index. Since an insertion sort does exactly that, without any additional logic or datastructure, you might as well use it.
The only exception is if your comparison is particularly expensive. If that is the case, then you can use a binary search to find your insertion point (instead of comparing your new element against each old element as you move it). However, you will still need to move all elements larger than the mutation point, so you will never be able to improve your performance past O(N) (although a bulk data move should be pretty fast...).
Also, you should evaluate your requirements: if you know that N < 256
, and the worst case of inserting an object in position 0
is fast enough for your application, you should stop there. There's no point in making things more complicated than necessary, to save time you don't need.
On the other hand, if:
then what you need is called a priority queue, and you can implement it (in memory-efficient, in-place fashion) by using an implicit heap. Implicit heap operations are O(log N), and typically have a good performance factor; even for N = 255
, this can make a big difference in worst-case performance.
I often use this algo in microcontroller environment, it keeps the table always sorted. It doesn't use binary lookup, but the loop that searches a greater element will run faster then binary algorithm if you only going to use it for a small number of elements. For larger arrays, you may want to do a binary lookup.
This algorithm is also very easy to implement in assembler and only uses 2 additional int's on stack.
#define TABLE_SIZE 255
int table[TABLE_SIZE];
int tableUsed = 0;
bool AddToTable(int value)
{
int i;
if (tableUsed >= TABLE_SIZE)
return false;
// Find location to insert value
for (i = 0; i < tableUsed; i++)
if (table[i] > value)
break;
// Insert value
do
{
table[i] ^= value;
value ^= table[i];
table[i] ^= value;
} while (i++ < tableUsed);
tableUsed++;
return true;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With