I have an usort() example and I added some echo statements to see how the code works:
<?php
function list_cmp($a, $b) {
global $order;
echo "\$a=$a, \$b=$b </br>";
foreach ($order as $key => $value) {
echo "\$value=$value </br>";
if ($a == $value) {
echo "\$a=\$value, returing 0. </br>";
return 0;
}
if ($b == $value) {
echo "\$b=\$value, returing 1. </br>";
return 1;
}
}
}
$order[0] = 1;
$order[1] = 3;
$order[2] = 4;
$order[3] = 2;
$array[0] = 2;
$array[1] = 1;
$array[2] = 3;
$array[3] = 4;
$array[4] = 2;
array[5] = 1;
$array[6] = 2;
usort($array, "list_cmp");
?>
The output of the code is this:
$a=2, $b=1
$value=1
$b=$value, returing 1.
$a=2, $b=3
$value=1
$value=3
$b=$value, returing 1.
$a=1, $b=3
$value=1
$a=$value, returing 0.
$a=2, $b=4
$value=1
$value=3
$value=4
$b=$value, returing 1.
$a=3, $b=4
$value=1
$value=3
$a=$value, returing 0.
$a=2, $b=2
$value=1
$value=3
$value=4
$value=2
$a=$value, returing 0.
$a=2, $b=1
$value=1
$b=$value, returing 1.
$a=2, $b=1
$value=1
$b=$value, returing 1.
$a=4, $b=1
$value=1
$b=$value, returing 1.
$a=3, $b=1
$value=1
$b=$value, returing 1.
$a=1, $b=1
$value=1
$a=$value, returing 0.
$a=2, $b=2
$value=1
$value=3
$value=4
$value=2
$a=$value, returing 0.
What is the mechanism of creating the 12 $a-$b pairs - 2-1, 2-3, 1-3, 2-4, 3-4, 2-2, 2-1, 2-1 (the same again?), 4-1, 3-1, 1-1, 2-2. The above code returns 1,1,0,1,0,0,1,1,1,1,0,0. And also what is the mechanism of sorting the array, based on the values that get returned? I am trying to understand how the usort() mechanism works.
Thanks.
I'm not sure wether this was part of the question, but to be clear about how the comparator works: You have an order specified by ordered list
$order
and a special comparator callbacklist_cmp
which (should) return wether argument$a
is smaller than$b
(return -1
or a value< 0
)$a
greater than$b
(return 1
or a value> 0
)$a
equal$b
(return 0
)list_cmp
does this by looking up its order table and rather checking if$a
has a smaller (or equal) order in which case the loop exits early withreturn 0
or if$b
has a smaller order in which case the loop exits early withreturn 1
.Be aware that this is wrong according to the PHP Documentation which states it wants positive/negative/0 as return values. This is only correct if you know that the internals only check for
comparator($a,$b) > 0
, meaning it only checks if$b
is smaller than and not equal to$a
, making this a comparisonorder of $a <= order of $b
. It can easily break if the code starts to check for$a
being smaller than and not equal to$b
.quicksortsorting work?For starters I'm assuming you are using PHP 7 or higher. In that case you hit a special case with 6-15 Element sized arrays. PHP 7+ does not seem to use quicksort for short lists, instead it uses an Insertion Sort Variant (which is most probably faster due to Hardware related stuff like caching/code locality). You can check the sorting source code f.e. on the Github PHP Mirror (as an example: PHP 7.0 Zend/Zend_sort.c Line 177-198).
The code works in 3 steps:
array[j]
andarray[j+1]
, ifarray[j] <= array[j+1]
move on, else goto 2.array[j] > array[j+1]
, scan backwards to find the point wherearray[x] < array[j+1] <= array[x+1]
forx < j
(obviously only untilx
hits the start)x+1 ... j
one up such that it becomesx+2 ... j+1
and insert former element at positionx+1
If you apply that code to the pairings (2-1, 2-3, 1-3, 2-4, 3-4, 2-2, 2-1, 2-1, 4-1, 3-1, 1-1, 2-2) it gets obvious what the code does.
PS: Here you already see that it is quite complex to derive the work of even a simple sorting algorithm (22 lines of code) by its comparison patterns. The PHP 7 quicksort implementation is around 10 times as big in lines of code and has some freaky optimizations (besides normal madness due to pivot selection and recursions).
Most of the times it is better to ignore in depth implementation details and only reduce it to the stuff that is needed. Typical questions for a sorting algorithm would be if it is stable/unstable and performing in
O(log n)
withO(n)
Memory consumption. There are easier ways to learn the core algorithms behind those optimized implementations like the Quicksort Dance or any other visualization or a good old (e)book or webpage with examples.-- Edited
Added a (bad, unoptimized, unsafe) php implementation for insertion sort for another visualization of how it works:
Output is complete now with currently sorted array, positions: