Introduction
Unsurprisingly, insertion sort does just what it sounds like--every subsequent element is inserted into its correct, sorted position within an array.
This comprehensive guide will cover all the bases of insertion sort, from its pros and cons and an implementation within C, to calculations of its time complexity.
Why Insertion Sort?
When dealing with sorting algorithms, programmers face compromise between time and memory--while some sorting methods are faster than others, they tend to use up more memory, and vice versa.
Insertion sort is something of the latter, taking up less memory, but also being a generally slower algorithm.
Advantages:
Ideal for small and nearly-sorted lists
In-place sorting algorithm
doesn’t require any additional memory, as all of the sorting occurs within the same array
basically, the program doesn’t create a new, temporary array for storage
Stable sorting algorithm
relative order of elements is preserved once sorted
Disadvantages:
Not so efficient for large lists
Insertion Sort in C
Before we jump into a full-fledged implementation of this sorting algorithm in C, it's always a good idea to have a general idea of what the program intends to do on a higher-level--that's where pseudocode comes in handy.
Starting with the second element in the list, insertion sort looks at all the elements to the left of the "current element" and compares them
If the element has not reached the beginning of the list AND if its value is less than the element to its left, the value checked is shifted one place to the right
If the element has reached the very beginning of the list OR if its value is greater than the element to its left, the element is placed there
This process continues until all elements in the list have been compared with the values to their left
Let's use the list [ 2, 5, 3, 9, 0 ] to simulate this. The number highlighted is the one being compared to the values to its left, and respectively inserted.
[ 2, 5, 3, 9, 0]
[ 2, 3, 5, 9, 0]
[ 2, 3, 5, 9, 0]
[ 0, 2, 3, 5, 9]
Now that we've established how this algorithm should work in theory, let's have a look at its formal implementation in C.
Note that the comments (denoted with //) can be helpful in understanding what each part of the program does!
#include <stdio.h>
// function prototype
void insertionSort(int arr[], int n);
int main()
{
// initialize array, array length
int array[] = {2, 5, 3, 9, 0};
int length = sizeof(array) / sizeof(array[0]);
// function call
insertionSort(array, length);
}
void insertionSort(int arr[], int n)
{
// insertion sort
// begins at second element
for (int i = 1; i < n; i++)
{
int j = i-1;
int curNum = arr[i];
// checks if elements to the left haven't reached the beginning or are greater than the current number being compared
while (j >= 0 && curNum < arr[j])
{
// if so, shift the element to the right and change j one to the left
arr[j+1] = arr[j];
j--;
}
// once j has reached index -1 or the current number is greater than a value to its left, it gets inserted there
arr[j+1] = curNum;
}
// prints array
for (int i = 0; i < n; i++)
{
printf("%i", arr[i]);
}
}
Calculating Time Complexity
Time Complexity is a measure of how efficient the program in terms of the amount of time it takes to run (and thus, the number of steps required to run the algorithm).
Of course, programs can vary in time complexity depending on how elements are placed in the original array, so we can account for the worst case and best case scenario using Big-O and Big-Omega notations (respectively), on which you can find more about in my CS50's Week 3 blog!
Best Case Scenario: all elements in the array are pre-sorted
In the case that all elements are sorted, only the outer for loop would run (as the conditions for the while loop would never be met). Thus, the program would run n -1 times, where n is the number of elements in the list.
Mathematically...
n - 1
Σ 1 = n-1
i = 1
Because n is the most prominent term, we can express this as Ω(n).
Worst Case Scenario: all elements in the array are in reverse order
Here, not only would the outer loop run n-1 times, but the inner loop would run i times, where i is the number of places from the current element to the beginning of the list.
Mathematically...
n - 1 i - 1 n - 1
Σ Σ 1 = Σ i = (1/2)(n-1)(n)
i = 1 j = 0 i = 1
Because the most prominent term is n^2, we can express this as Ο(n^2).
Final Thoughts
Ultimately, insertion sort can be an asset when working with specific datasets, so it can be especially useful to know the time and place for which using a sorting algorithm will help you (or harm you).
That's all for insertion sort!
Comentarios