Sorting for app.codility.com/programmers Explained in PHP
Category of Article : Technology | Computers and Software | Algorithm
By: Chrysanthus Date Published: 2 Jul 2025
| Index | 0 | 1 | 2 | 3 | 4 | 5 |
|---|---|---|---|---|---|---|
| Element | 5 | 2 | 8 | 14 | 1 | 16 |
| Index | 0 | 1 | 2 | 3 | 4 | 5 |
|---|---|---|---|---|---|---|
| Element | 1 | 2 | 5 | 8 | 14 | 16 |
Bubble Sort
The simplest sorting algorithm is the bubble sort algorithm. Given an unsorted list, and starting from the left end, the algorithm swaps the first two elements if they are not in order. It then swaps the next two elements if they are not in order. One element would be from the first swap, if swapping took place there. It swaps the following two elements; one element would be from the previous swap if swapping took place there. This continues until the element at the extreme right is addressed. The whole list is re-scanned in that fashion; over and over, until the list is completely sorted. In this section of the lesson (tutorial), sort ascending for bubble sort is considered.Bubble Sort Illustration
Consider the following unsorted list:R X F S U Z V JThere are 8 elements, which need 8 complete scans, for bubble sort, resulting in
R F S U X V J ZThe final list arrangement is the complete sort.
F R S U V J X Z
F R S U J V X Z
F R S J U V X Z
F R J S U V X Z
F J R S U V X Z
F J R S U V X Z
F J R S U V X Z
Worst-Case Performance
The PHP code to sort the above eight characters, as explained above is:
<?php
function bubbleSort($arr, $N) {
global $arr;
$counter = 0;
for ($i = 0; $i < $N; $i++) { //number of rows
for ($j = 1; $j < $N; $j++) {
if ($arr[$j] < $arr[$j - 1]) {
$temp = $arr[$j];
$arr[$j] = $arr[$j - 1];
$arr[$j - 1] = $temp;
}
$counter+=1;
}
}
echo $counter . "\n";
}
$arr = ['R', 'X', 'F', 'S', 'U', 'Z', 'V', 'J'];
bubbleSort($arr, 8);
for ($i = 0; $i < 8; $i++)
echo $arr[$i] . ', ';
echo "\n";
?>
The code for swapping is in the inner nested for-loop. The counter counts the number of basic (main) operations. The outer for-loop loops from 0 to 7, i.e., 8 times. The inner for-loop loops from 1 to 7, i.e., 7 times. The total number of basic operations (inner for-loop) is 8 x 7 = 56. The counter output is 56.If the inner for-loop looped from 0 to 7, then the total number of basic operations would have been 8 x 8 = 64. This is the maximum number of basic operations for this nesting for-loops. Let 8 be n. Then, the maximum number of such nesting for-loops is n2.
The worst-case time complexity for the previous function (nested for-loops) is given as, O(n2).
The big O followed by its parentheses with n2, is the big-O notation. It indicates the relative speed of the code. Though in the above code, the number of basic operations is 56, the maximum possible number of operations, 82 = 64, is what would be given for the time complexity.
Better Performance for Bubble Sort
Notice in the above illustration for the bubble sort; that after the first scan, the highest element is at the right end. After the second scan, the highest two elements are at the right end, in order. After the third scan, the highest three elements are at the right end, in order, and so on. Operations on these extreme-right elements as they grow, can be omitted in coding. This would increase overall speed (time for complete sorting). The following modified function illustrates this:
<?php
function bubbleSort($arr, $N) {
global $arr;
$counter = 0;
for ($i = 0; $i < $N; $i++) {
for ($j = 1; $j < $N-$i; $j++) {
if ($arr[$j] < $arr[$j - 1]) {
$temp = $arr[$j];
$arr[$j] = $arr[$j - 1];
$arr[$j - 1] = $temp;
}
$counter+=1;
}
}
echo $counter . "\n";
}
$arr = ['R', 'X', 'F', 'S', 'U', 'Z', 'V', 'J'];
bubbleSort($arr, 8);
for ($i = 0; $i < 8; $i++)
echo $arr[$i] . ', ';
echo "\n";
?>
This time, the counter output is 28. The number of basic operations is 28, slightly less than half of 64, which is 32. Twenty-eight is quite less than 56. The inner for-loop loops from 1 to N - i. In its first scan, i is zero, and n - i = 8.Now,
2 x 2 x 2 = 8
=> 23 = 8
=> 8 = 23 (swapping left hand side of = with right-hand side)
log2 8 = log2 23 (definition)
= 3
8 x 3 = 8xlog2 23
= 24
which is close to 28. Let n = 8. The last-but-one right operand expression above, becomes n.log2(23), = n.log2 8, generally written as, n.log n , with the 2 as base omitted.
So, the time complexity for the improved performance of bubble sort is above O(n.log n), and less than O(n2).
Note: the counting of the number of times the main operation occurs, by the counter, is not supposed to be part of the code. It is there to indicate the time complexity.
Some Interspersed Sequence of Elements Already Sorted
There are eight scans for the previous bubble sort illustration. Notice that by the sixth scan, the list was completely already sorted. The last two rows are repetitions of the sixth row. For this particular unsorted list, the last two scans were not necessary. This happens when the given unsorted list has some already sorted interspersed sequences. If the given list is completely unsorted, then the last row would be the final sorted list (it would not be a repetition of the previous).Again, the worst-case time complexity for bubble sort is:
O(n2)
With the improvement of code, the time complexity can be about O(n.log n).
Selection Sort
For selection sort, find the minimal element and swap it with the first element of the array. Continue by sorting the rest of the array, in the same way, iterating. This is sort ascending. There are two for-loops, the inner for-loop nested in the outer for-loop.At the start, the first minimal element is assumed to be the first element (at index 0). The whole list is then searched by the inner for-loop, for the least element less than the first element, beginning from the second element. If found this least element is swapped with the first element using the outer for-loop. Next, the inner for-loop beginning from the third element, searches for the least element less than the second element. If found this new least element is swapped with the second element using the outer for-loop. Next, the inner for-loop beginning from the fourth element, searches for the least element less than the third element. If found this new least element is swapped with the third element using the outer for-loop. This continues till the end of the array. The inner for-loop actually looks for the index of least element and not really the least element itself. The following program illustrates selection sort:
<?php
function selectionSort($arr, $N) {
global $arr;
$counter = 0;
for ($i = 0; $i < $N; $i++) {
$minElemIndx = $i;
for ($j = $i+1; $j < $N; $j++) {
if ($arr[$j] < $arr[$minElemIndx]) {
$minElemIndx = $j;
}
$counter+=1;
}
//swapping code
$temp = $arr[$minElemIndx];
$arr[$minElemIndx] = $arr[$i];
$arr[$i] = $temp;
}
echo $counter . "\n";
}
$arr = ['R', 'X', 'F', 'S', 'U', 'Z', 'V', 'J'];
selectionSort($arr, 8);
for ($i = 0; $i < 8; $i++)
echo $arr[$i] . ', ';
echo "\n";
?>
The output is:28
F, J, R, S, U, V, X, Z,
The list (array) has 8 elements. The counter says that there are 28 operations (out of 64 possible operations). Accept that the worse-case performance for selection sort is O(n2), when the list is completely un-sorted.
Note that the counter is not supposed to be there in the code. It is there just to give the number of operations (time complexity).
Insertion Sort
InsertionSort correctly places the value of A[i] with respect to the values already arranged among the values A[0] to A[i-1] (inclusive); where A is the array name and i is the zero based index variable. With ascending sort, if A[i] > A[i-1], there is no placement (no displacement). In order to place A[i] correctly, there has to be some movement of values within A[0] to A[i-1] (inclusive), one step to the right. Consider the following list of 8 characters, which are considered completely unsorted, though completely sorted in descending order:Z X V U S R J F
The aim is to do insertion sort on this in ascending order. Firstly, Z and X are compared. X is less than Z. So X is copied to a temporary variable. Z is shifted one place up (to the right). From the temporary variable, X is copied to the first place, where Z was. The result is:
X Z V U S R J F
That is considered as one main operation. X and Z are now sorted, though they are not in their proper positions. Next, V is compared with Z and then with X. V is less than Z and is also less than X. X and Z are displaced one place each, to the right, and V is fitted in the first position. The result is:
V X Z U S R J F
That is considered as two main operations. V, X and Z are now sorted, though they are not in their proper positions. Next, U is compared with Z, X and V. U is less than Z, X and V. U is now at index 3. A place from index 0 to index 2 has to be look for in order to insert U. This place happens to be the first position. V, X and Z are displaced one place each, to the right, and U is fitted in the first position. The result is:
U V X Z S R J F
That is considered as three main operations. U, V, X and Z are now sorted, though they are not in their proper positions. Next, S is compared with Z, X, V and U. S is less than Z, X, V and U. S is now at index 4. A place from index 0 to index 3 has to be look for in order to insert S. The best way to do this is just by comparing S with the already sorted characters in reverse order; that is comparing S, first with Z, then with X going downwards until its place is found. In this situation, this place happens to be the first position. U, V, X and Z are displaced one place each, to the right, and S is fitted in the first position. The result is:
S U V X Z R J F
That is considered as four main operations. S, U, V, X and Z are now sorted, though they are not in their proper positions. Next, R is compared with Z, X, V, U and S. R is less than Z, X, V, U and S. R is now at index 5. A place from index 0 to index 4 has to be look for, in order to insert R. The best way to do this is just by comparing R with the already sorted characters in reverse order; that is comparing R, first with Z, then with X, then with V, going downwards until its place is found. In this situation, this place happens to be the first position. S, U, V, X and Z are displaced one place each, to the right, and R is fitted in the first position. The result is:
R S U V X Z J F
That is considered as five main operations. R, S, U, V, X and Z are now sorted, though they are not in their proper positions. Next, J is compared with Z, X, V, U, S and R. J is less than Z, X, V, U, S and R. J is now at index 6. A place from index 0 to index 5 has to be look for, in order to insert J. The best way to do this is just by comparing R with the already sorted characters on the left, in reverse order; that is comparing J, first with Z, then with X, then with V, going downwards until its place is found. In this situation, this place happens to be the first position. R, S, U, V, X and Z are displaced one place each, to the right, and J is fitted in the first position. The result is:
J R S U V X Z F
That is considered as six main operations. J, R, S, U, V, X and Z are now sorted, though they are not in their proper positions. Next, F is compared with Z, X, V, U, S, R and J. F is less than Z, X, V, U, S, R and J. F is now at index 7. A place from index 0 to index 6 has to be look for, in order to insert F. The best way to do this is just by comparing F with the already sorted characters on the left, in reverse order; that is comparing F, first with Z, then with X, then with V, going downwards until its place is found. In this situation, this place happens to be the first position. J, R, S, U, V, X and Z are displaced one place each, to the right, and J is fitted in the first position. The result is:
F J R S U V X Z
That is considered as seven main operations. F, J, R, S, U, V, X and Z are now sorted, and they are in their proper positions.
The worst case performance occurs when the unsorted array is actually sorted in reverse order. In this situation the number of main operations for 8 elements is:
1 + 2 + 3 + 4 + 5 + 6 + 7 = 28
Well, with insertion sort the comparison is considered as one main operation and the displacement and insertion is also considered as one main operation. For simplicity, in this document, both are considered as one main operation. So the number of main operations in this case is 28, which is greater than 24 = 8.log28 and less than 64 = 82. The time complexity for the worse case performance is O(n2). Remember that the official value is the maximum, O(n2).
Average case performance occurs when the unsorted array has some intersperse sorting already. In this situation, A[i] is not always less than A[i-1] in the sorting algorithm. The time complexity for average case performance is O(n2/2). Since it is the maximum that is considered, the time complexity for average case performance is taken as O(n2).
Best case performance occurs when the given list is already sorted. In this situation only the comparisons are made, and no displacement and insertion is made. The time complexity here is O(n), i.e. linear (actually O(n-1), for example, 7 out of 8 comparisons above). For 8 elements, 7 comparisons is slightly less than 8, and so the maximum, O(8) is chosen for time complexity.
Insertion Sort in PHP
The insertion code in PHP is:
<?php
function insertionSort($A) {
global $A;
$n = count($A);
for ($i=1; $i < $n; $i++) {
if ($A[$i] < $A[$i-1]) { //first comparison
$temp = $A[$i];
$j = $i;
do {
$A[$j] = $A[$j-1]; //shifting (displacement)
--$j;
} while ($temp < $A[$j-1]&&($j>0)); //comparison continuous while j>0
$A[$j] = $temp;
}
}
}
$A = ['Z', 'J', 'V', 'S', 'U', 'R', 'X', 'F'];
insertionSort($A);
for ($i=0; $i < count($A); $i++)
echo $A[$i] . ' ';
echo "\n";
?>
The output is:F J R S U V X Z
as expected.
Counting Sort
What is Counting Sort?
Counting sort is best illustrated with the sorting of integers. In C/PHP and Java, characters are integers and can be sorted in the way integers are sorted. Consider the following unsorted list of integers:16, 20, 12, 10, 18, 8, 12, 18, 12, 14
This list is to be sorted in ascending order. It can be given (to a sorting program) as an array. It consists of positive numbers greater than or equal to 0.
Notice here that the highest integer is 20. So, 20 + 1 = 21 new array locations have to be provided. The extra 1 is for the possibility that, in the given array, one of the integers to be sorted is 0. Remember that the sorting program does not know the numbers to be sorted in advance. So, the possibility of having 0 should be made (21 new array locations instead of 20).
For each index of the new array that is a value in the given list, the number of occurrence of that value in the given list is assigned as the value for that new array cell. That is, the new array consists of counters. The previous unsorted list is represented as follows, in the new array:
|
count |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
0 |
1 |
0 |
3 |
0 |
1 |
0 |
1 |
0 |
2 |
0 |
1 |
|
index |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
The total number of counts gives the number of elements in the unsorted list. This table represents the second array which is the new array of counters. At this stage, there are two arrays: the given array of the unsorted list and the array of counters, called the count array.
In the table, the second row has the indexes, which are values of the given array. The first row has the counts. Each count is the number of occurrence of the corresponding index in the new array, that is found as value in the unsorted list.
For the indexes 0 to 7 (inclusive), each count is 0. This is because none of these indexes is a value in the given unsorted list. The index 8 occurs once in the given list, so its count is 1. The index 9 occurs zero time in the given list, so its count is 0. The index 10 occurs once in the given list, so its count is 1. The index 12 occurs three times in the given list, so its count is 3. The index 13 occurs zero time in the given list, so its count is 0. This continues until the index 20 with a count of 1, while the index 18 has a count of 2. There are actually 21 cells in the table, due to the included 0.
The sorted list is as follows:
8, 10, 12, 12, 12, 14, 16, 18, 18, 20
This is obtained from the count (new) array as follows:
Moving from left to right of the second array, if the count value of an index is 0, then that index as value, is not in the given unsorted list (array), and should not appear in the sorted list. If the value is 1, write the index once, for the sorted list. If the value is 2, write the index twice, for the sorted list. If the value is 3, write the index three times. If the value is 4, write the index 4 times, and so on.
Counting Sort Algorithm
• Create an array whose length is the maximum number in the unsorted list, plus 1 (to account for a possible 0 in the given list). An index of this array is a possible value in the unsorted list. This new (second) array is the count array, where the value in each of its cells, is the number of occurrence of the value in the unsorted aarray.
• Read the count array from left to right, while writing the index whose cell value is not 0, the number of times, it occurs in the given array. The number of times is the count in the count array. This is sort ascending.
Operations
For the above given unsorted list, the maximum value is 20. So the new array has to be given 21 values (the extra 1 being for a possible 0 unsorted values). Creating this array with its values initialized to 0, consists of 21 main operations.
Time Complexity for Counting Sort
The time complexity is given in general terms as,
O(n+m)
In the above case, m is 21. In practice, the new array is said to be created and all elements initialized to 0 in m time. The counts (number of occurrences for each unsorted value), are given to the new array in n time; where n is the total number of elements in the unsorted list (array). Each count that is more than 1 is done by incrementing, the number of times the value repeats in the unsorted list, as the unsorted list itself is scanned (from left to right).
Memory Space
Notice that in the above count array, all the counts of 0 are redundant. Though their spaces are redundant in memory, they have to be there. The counting sort takes unnecessary memory space in general. Nothing is normally done to avoid the redundant locations.
Note: There is also space complexity, but that is not addressed in this tutorial (lesson).
Coding in PHP
A Counting Sort function in the PHP computer language is as follows:
<?php
function countingSort($arr, $n, $max) {
global $arr;
//m time complexity
$count = array_fill(0, $max+1, 0);
//n time complexity
for ($i = 0; $i < $n; $i++) {
$count[$arr[$i]] = $count[$arr[$i]] + 1; //add 1 for each occurrence of same value
}
//optional additional m time complexity
$k = 0; //index for given array
for ($i=0; $i < $max+1; $i++) {
if ($count[$i] != 0) {
for ($j=0; $j < $count[$i]; $j++) { //accounting for repetition where necessary
$arr[$k] = $i; //putting back sorted value into given array
$k++;
}
}
}
}
n is the number of elements in the given array. max is the maximum element in the given array.
A suitable PHP calling function code segment is as follows:
$arr = [16, 20, 12, 10, 18, 8, 12, 18, 12, 14];
countingSort($arr, 10, 20);
for ($i=0; $i < 10; $i++)
echo $arr[$i] . ', ';
echo "\n";
The output is:
8 10 12 12 12 14 16 18 18 20
Merge Sort
Many computer languages today have a general-purpose sort() function in their library. This function is used for commercial applications. Many programmers use the sort function provided by the language library, whenever they need a sort function.
The mergesort program, written normally, is comparable (in terms of speed) to the sort() function provided by PHP in its algorithm library. Merge-sort is also a general purpose commercial program.
This section of the tutorial (lesson) explains how to write the mergesort program in the PHP language.
Divide-and-Conquer Algorithm, in its Broad Sense
In its broad sense, the array of elements is divided into two halves: the left half and the right half. If the total number of elements to be sorted is odd, then the left half is bigger than the right half, by 1 unit, as a result of integer division. Otherwise, both halves are of the same length. The two halves are then merged while sorting to form one sorted array. The merging/sorting is conquering. Consider the following characters to be sorted:
Q W E R T Y U I O P
Dividing this set of alphabetic characters into two halves, gives:
Q W E R T Y U I O P
A sub array is called a run. So the left sub array, “Q W E R T” is a run and the right sub array, “Y U I O P” is also a run. A run can only finally consist of one element.
Merging/sorting (conquering) both halves into one set gives:
E I O P Q R T U W Y
The code segment to divide by 2 is:
$mid = (int)($n / 2);
$left = array_slice($arr, 0, $mid);
$right = array_slice($arr, $mid);
This uses integer division. So, the whole number part of the result is taken. With this, if the total number of elements in the set is odd then the left half would be bigger than the right half, by 1 unit for zero based indexing.
Practical Mergesort Divide-and-Conquer Algorithm
A mergesort operates conceptually in the following way:
1) Divide the unsorted set into N subsets (runs), where each has one element. Note that a set with only one element is considered sorted.
2) Repeatedly merge subsets to obtain new sorted subsets, until only one subset is left, which is the whole sorted set.
The set, {'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P'}, is used to explain how mergesort is achieved practically, in this section.
The set is divided into the two sets:
{'Q', 'W', 'E', 'R', 'T'} and {'Y', 'U', 'I', 'O', 'P'}
The above two subsets are each, further divided into two, to have:
{'Q', 'W', 'E'} and {'R', 'T'} and {'Y', 'U', 'I'} and {'O', 'P'}
Note that for each new division here, the left subset is longer than the right subset by one unit.
The above subsets are each, further divided into two, to have:
{'Q', 'W'} and {'E'} and {'R'} and {'T'} and {'Y', 'U'} and {'I'} and {'O'} and {'P'}
Here, some subsets cannot be divided any more because they each consists of one element. After that, division of the more than one length subsets above, leads to:
{'Q'} and {'W'} and {'E'} and {'R'} and {'T'} and {'Y'} and {'U'} and {'I'} and {'O'} and {'P'}
From here, {'Q'} and {'W'} will be sorted and merged into {'Q', 'W'}. {'E'} and {'R'} will be sorted and merged into {'E', 'R'}. {'T'}. {'Y'} will be sorted and merged into {'T', 'Y'}. {'U'} and {'I'} will be sorted and merged into {'I', 'U'}. {'O'} and {'P'} will be sorted and merged into {'O', 'P'}.
Next: {'Q', 'W'} and {'E', 'R'} will be sorted and merged into {'E', 'Q', 'R', 'W'}. {'T', 'Y'} and {'I', 'U'} will be sorted and merged into, {'I', 'T', 'U', 'Y'}. At this stage, {'O', 'P'} is not joined with any previous subsets of two.
The next stage: {'E', 'Q', 'R', 'W'} and {'I', 'T', 'U', 'Y'} are sorted and merged into {'E', 'I', 'Q', 'R', 'T', 'U', 'W', 'Y'}. At this stage, {'O', 'P'} again is not joined with any of the previous subsets.
The last stage: {'E', 'I', 'Q', 'R', 'T', 'U', 'W', 'Y'} and {'O', P'} are sorted and merged into
{'E', 'I', 'O', 'P', 'Q', 'R', 'T', 'U', 'W', 'Y'}.
The unsorted set has been sorted.
Coding mersort in PHP
A complete mergesort program is as follows:
<?php
function mergeSort(array $arr): array
{
$n = count($arr);
// Base case: if the array has 0 or 1 element, it's already sorted
if ($n <= 1) {
return $arr;
}
// Divide the array into two halves
$mid = (int)($n / 2);
$left = array_slice($arr, 0, $mid);
$right = array_slice($arr, $mid);
// Recursively sort both halves
$left = mergeSort($left);
$right = mergeSort($right);
// Merge the sorted halves
return merge($left, $right);
}
function merge(array $left, array $right): array
{
$result = [];
$leftIndex = 0;
$rightIndex = 0;
// Compare elements from both arrays and add the smaller one to the result
while ($leftIndex < count($left) && $rightIndex < count($right)) {
if ($left[$leftIndex] <= $right[$rightIndex]) {
$result[] = $left[$leftIndex];
$leftIndex++;
} else {
$result[] = $right[$rightIndex];
$rightIndex++;
}
}
// Add any remaining elements from the left array
while ($leftIndex < count($left)) {
$result[] = $left[$leftIndex];
$leftIndex++;
}
// Add any remaining elements from the right array
while ($rightIndex < count($right)) {
$result[] = $right[$rightIndex];
$rightIndex++;
}
return $result;
}
// Example usage:
$testArray = ['Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P'];
echo "Original Array: " . implode(", ", $testArray) . "\n";
$sortedArray = mergeSort($testArray);
echo "Sorted Array: " . implode(", ", $sortedArray) . "\n";
?>
The output is:
Original Array: Q, W, E, R, T, Y, U, I, O, P Sorted Array: E, I, O, P, Q, R, T, U, W, Y
Merge Sort Time Complexity
Time complexity is the relative running time of a program. It can be seen as the number of the main operations of a program.
Integer Division by Two
Integer division is necessary when doing a merge sort.
Now,
6 ÷ 2 = 3 R 0
7 ÷ 2 = 3 R 1
When an even number is divided by 2, the remainder is 0. When an odd number is divided by 2 the remainder is 1. With integer division, the whole number is taken and the remainder is abandoned.
Merge Sort Algorithm
Merge Sort is a divide and conquer sorting algorithm. A simplified explanation is as follows: In this algorithm, the unsorted list is divided into two halves using the integer division. Each of the halves is further divided into two halves again using the integer division. This division continues until the list is considered as single separate elements.
Beginning from the left, the consecutive elements are then paired in a sorted manner. The paired elements are then paired again in a sorted form. This grouping by pairs continues until the whole list is reformed and sorted.
Linear and Logarithmic Time Complexity
Consider the following code in the PHP language:
for ($i=0; $i < $8; $i++) {
$k = $i + 1;
echo $k . ' ';
}
echo "\ns";
The output is:
1 2 3 4 5 6 7 8
The code is a for-loop (ignoring the print statement just after the for-loop). It prints the integers from 1 to 8, for a total of 8 numbers. The content of the body of the for-loop is:
$k = $i + 1;
echo $k . ' ';
These two statements are considered as one main operation in this situation. There are 8 operations, with the 8 iterations. Let n be 8. This is a linear time complexity and it is written as follows:
O(n)
where n is the possible maximum number of operations. This is the Big-O notation. It begins with O in uppercase and followed by parentheses. Inside the parentheses is the maximum possible number of operations.
Consider now the following code where out of 8 numbers, 3 numbers are printed:
for ($i=0; $i<8; $i++) {
$k = $i + 1;
echo $k . ' ';
if ($k == 3) break;
}
echo "\n";
The output is:
1 2 3
The code is a for-loop (ignoring the print statement just after the for-loop). It prints the integers from 1 to 3 out of 8 numbers. The content of the body of the for-loop is:
$k = $i + 1;
echo $k . ' ';
if ($k == 3) break;
Still, these three statements are considered as one main operation in this situation. There are 3 main operations out of 8, with three iterations.
Now,
8 = 23
=> 3 = log2(8)
So, the number of main operations carried out by the previous code is 3 (out of 8).
Let n be 8. This is a logarithmic time complexity and it is written as:
O(log2n)
where (log2 n) means 3 for the above code.
Example of Unsorted and Sorted List
An example of an unsorted list is as follows:
P V D Q S X T B
There are eight elements in the list. When this list is sorted, it becomes:
B D P Q S T V X
Counting the Number of Main Operations in the Merge Sort
The following list:
P V D Q S X T B
is used to count the number of the main operations in merge sort.
The integer division by two gives the following result:
P V D Q S X T B
This is one operation. Another division of both parts by two gives the following result:
P V D Q S X T B
These are three operations so far (one plus two). Another division of each new part by two gives the following result:
P V D Q S X T B
These are seven operations so far (three plus four). The list of the eight elements are now considered as eight separate elements with a total of seven operations so far. The next phase is to pair while (arranging) sorting, beginning from the left. So, the next result is:
P V D Q S X B T
There are two changes in position for the last pair. Two changes are two operations. This makes a total of nine operations so far (seven plus two).
The pairing and sorting continues, always beginning from the left to give the following result:
D P Q V B S T X
Each of these two groups had four changes in position, making eight operations. There are seventeen operations so far (nine plus eight). The pairing and sorting continues and lastly, to give the following result:
B D P Q S T V X
There are seven changes in position here, making seven operations. This makes twenty-four operations (seventeen plus seven) for the complete sorting.
Time Complexity Proper, for Merge Sort
The previous counting (illustration) is used to quote the time complexity for the mergesort. There are twenty-four operations.
24 = 8 x 3
That is:
24 = 8 x log2(8)
because log2(8) is 3.
Let 8 be n. With that, the mergesort time complexity is given by:
O(n.log2n)
where the dot means multiplication.
In practice, out of 8 elements, the number of operations is approximately 24 or 24.
Conclusion for Mergesort Time complexity
The mergesort is a particular divide and conquer sorting algorithm. It is a very efficient sorting algorithm. Its time complexity is very satisfactory, compared to the other sorting algorithms. Its time complexity is:
O(nlog2n)
Note: The number of operations must not necessarily be exactly n.log2n . However, it can be slightly less.
Coding mergesort needs recursive functions. It is not too difficult to code it once the algorithm has been understood.
General Remark
In sorting, the term “non-descending” is normally used instead of ascending, to allow for duplicate values. The term “ascending” has been used above, for easy understanding.
Thanks for reading. Now go ahead and practice the next four tasks; solutions and their explanations are given.
The rest of the 17 lessons, with explanation of lessons, explanation of tasks, and explanation of solutions, can be found at (click): Explanations in PHP for the 17 Algorithm Lessons at https://app.codility.com/programmers with Problems and Solutions
Related Links
Basics of PHP with Security ConsiderationsWhite Space in PHP
PHP Data Types with Security Considerations
PHP Variables with Security Considerations
PHP Operators with Security Considerations
PHP Control Structures with Security Considerations
PHP String with Security Considerations
PHP Arrays with Security Considerations
PHP Functions with Security Considerations
PHP Return Statement
Exception Handling in PHP
Variable Scope in PHP
Constant in PHP
PHP Classes and Objects
Reference in PHP
PHP Regular Expressions with Security Considerations
Date and Time in PHP with Security Considerations
Files and Directories with Security Considerations in PHP
Writing a PHP Command Line Tool
PHP Core Number Basics and Testing
Validating Input in PHP
PHP Eval Function and Security Risks
PHP Multi-Dimensional Array with Security Consideration
Mathematics Functions for Everybody in PHP
PHP Cheat Sheet and Prevention Explained
More Related Links