PHP implementation of common sorting algorithms

Time:2021-7-29

This paper mainly introduces some common sorting algorithms and the code implementation of PHP, hoping to help you.

This article is from awaimai.com and recommended by fire dragon fruit software Luca.

As PHPer, the programming of general contact algorithm is not much.

But the basic sorting algorithm should be mastered.

After all, the algorithm is the core of the program, and the quality of the algorithm determines the quality of the program.

This paper will introduce some common sorting algorithms and PHP implementation in turn.

1 quick sort

Quick sort is a sort algorithm developed by Tony hall.

On average, n items need to be sorted Ο( N log (n) comparisons.

In the worst case, you need Ο( N2) times, but this situation is not common.

In fact, quick sort is usually significantly better than others Ο( The n log (n) algorithm is faster because its internal loop can be implemented efficiently on most architectures.

Quick sorting adopts divide and conquer method to realize sorting. The specific steps are as follows:

Select a number from the sequence as the reference element. Usually select the first or last element.

Scan the sequence, take the reference element as the comparison object, and divide the sequence into two areas. The rule is: move the small one to the front of the reference element, move the large one to the back, and the equal one can be both before and after. After partitioning, the base element is in the middle of the sequence.

Divide the two parts recursively, and then sort them in the same way.

The end condition of recursion is that the size of the sequence is 0 or 1, that is, it has always been sorted.

PHP code implementation:

function quickSort($arr)
 {
 $len = count($arr); 
 //Set the end condition first to judge whether to continue
 if($len <= 1) {
 return $arr;
 } 
 
 //Select the first element as the base element
 $pivot = $arr[0]; 
 
 //Initialize left array
 $left = $right = array(); 
 
//Initializes a right array larger than the base element
 $right = array(); 
 
 //Traverse all elements except the reference element and put them into the left and right arrays according to the size relationship
 for ($i = 1; $i < $len ; $i++) {
 if ($arr[$i] < $pivot) {
 $left[] = $arr[$i];
 } else {
 $right[] = $arr[$i];
 }
 } 
 
 //Then sort the left and right arrays in the same way
 $left = quickSort($left);
 $right = quickSort($right); 
 
 //Merge base elements and left and right arrays
 return array_merge($left, array($pivot), $right);
 }

Sort in place versions without additional storage space:


function partition(&$arr, $leftIndex, $rightIndex)
 {
 $pivot = $arr[($leftIndex + $rightIndex) / 2]; 
 while ($leftIndex <= $rightIndex) {
 while ($arr[$leftIndex] < $pivot) {
 $leftIndex++;
 }

 while ($arr[$rightIndex] > $pivot) {
 $rightIndex--;
 }
 
 if ($leftIndex <= $rightIndex) {
 list($arr[$leftIndex], $arr[$rightIndex]) = [$arr[$rightIndex], $arr[$leftIndex]]; 

 $leftIndex++;
 $rightIndex--;
 }
 } 

 return $leftIndex;
 }
 
function quickSort(&$arr, $leftIndex, $rightIndex)
 {
 if ($leftIndex < $rightIndex) {
 $index = partition($arr, $leftIndex, $rightIndex);
 
 quickSort($arr, $leftIndex, $index - 1);
 quickSort($arr, $index, $rightIndex);
 }
 } 

2 bubble sorting

Bubble sorting is a simple sorting algorithm.

The algorithm repeatedly visits the sequence to be sorted, compares two elements at a time, and exchanges them if their order is wrong.

The work of visiting the sequence is repeated until there is no need to exchange, that is, the sequence has been sorted.

Because the sorting process makes the larger number sink and the smaller number rise, it is called bubbling method.

Algorithm steps:

Start with the first element, compare adjacent elements, and exchange them if the first is larger than the second.

Do the same for each pair of adjacent elements from the first pair to the last pair at the end. After the comparison, the last element should be the maximum number.

Repeat the above steps for all elements except the last one.

Repeat the above steps, and the logarithm of each comparison will be less and less until there is no pair of numbers to compare.

PHP code implementation:


function bubbleSort($arr)
 {
 $len = count($arr);
 
 for($i = 1; $i < $len; $i++) {
 for($k = 0; $k < $len - $i; $k++) {
 if($arr[$k] > $arr[$k + 1]) {
 $tmp = $arr[$k + 1];
 $arr[$k + 1] = $arr[$k];
 $arr[$k] = $tmp;
 }
 }
 } 
 return $arr;
 }

3 insert sort

Insertion sorting is a simple and intuitive sorting algorithm.

The working principle of insertion sorting is to compare the number to be sorted with the data that has been sorted in front from back to front, so as to insert it into the corresponding position.

In the implementation of insertion sort, in place sort is usually used, that is, the sort that only needs the additional space of O (1).

Therefore, in the process of scanning from back to front, it is necessary to repeatedly move the sorted elements back step by step to provide insertion space for the latest elements.

Algorithm steps:

Starting from the first element, the element can be considered to have been sorted;

Take out the next element and scan from back to front in the sorted element sequence;

If the sorted element is larger than the new element, move the element to the next position;

Repeat step 3 until the sorted element is found to be less than or equal to the position of the new element;

Insert the new element into the position;

Repeat step 2.

PHP code implementation:


function insertSort($arr)
 {
 $len = count($arr); 
 
 for ($i = 1; $i < $len; $i++) {
 $tmp = $arr[$i];
 for ($j = $i - 1; $j >= 0; $j--) {
 if ($tmp < $arr[$j]) {
 $arr[$j + 1] = $arr[$j];
 $arr[$j] = $tmp;
 } else {
 break;
 }
 }
 }
 
 return $arr;
 }

4 select sort

Selective sorting is a simple and intuitive sorting algorithm.

Algorithm steps:

First, find the smallest element in the sequence and store it at the beginning of the sorting sequence;

Then, continue to find the smallest element from the remaining unordered elements and put it at the end of the sorted sequence.

Repeat step 2 until all elements are sorted.

PHP code implementation:


function selectSort($arr)
 {
 $len = count($arr); 
 for ($i = 0; $i < $len; $i++) {
 $p = $i;
 
 for ($j = $i + 1; $j < $len; $j++) {
 if ($arr[$p] > $arr[$j]) {
 $p = $j;
 }
 }
 
 $tmp = $arr[$p];
 $arr[$p] = $arr[$i];
 $arr[$i] = $tmp;
 }
 
 return $arr;
 }

5 merge sort

Merge sort is an effective sort algorithm based on merge operation.

Merge sort divides the sequence to be sorted into several groups to ensure that each group is orderly, and then merge sort to finally make the whole sequence orderly.

The algorithm is a very typical application of divide and conquer method.

Algorithm steps:

The application space is the sum of two sorted sequences, and the space is used to store the merged sequences;

Set two pointers. The initial position is the starting position of the two sorted sequences

Compare the elements pointed to by the two pointers, select the relatively small element, put it into the merge space, and move the pointer to the next position

Repeat step 3 until a pointer reaches the end of the sequence

Copy all the remaining elements of another sequence directly to the end of the merged sequence

Sorting effect:

PHP implementation code:

/**
 *Merge sort
 *
 * @param array $lists
 * @return array
 */
 function merge_sort(array $lists)
 {
 $n = count($lists);
 if ($n <= 1) {
 return $lists;
 }
 $left = merge_sort(array_slice($lists, 0, floor($n / 2)));
 $right = merge_sort(array_slice($lists, floor($n / 2)));
 $lists = merge($left, $right);
 return $lists;
 } 
function merge(array $left, array $right)
 {
 $lists = [];
 $i = $j = 0;
 while ($i < count($left) && $j < count($right)) {
 if ($left[$i] < $right[$j]) {
 $lists[] = $left[$i];
 $i++;
 } else {
 $lists[] = $right[$j];
 $j++;
 }
 }
 $lists = array_merge($lists, array_slice($left, $i));
 $lists = array_merge($lists, array_slice($right, $j));
 return $lists;
 }

6 heap sort

This sort algorithm refers to the heap sort algorithm.

Heap is a structure similar to a complete binary tree and satisfies the nature of heap: that is, the key value or index of a child node is always less than (or greater than) its parent node.

The average time complexity of heap sorting is Ο( nlogn) 。

Algorithm steps:

Create a heap h [0.. n-1];

Swap the head (maximum) and tail;

Reduce the size of the heap by 1 and call shift_ Down (0) to adjust the top data of the new array to the corresponding position;

Repeat step 2 until the heap size is 1.

PHP implementation code:

/**
 *Heap sort
 *
 * @param array $lists
 * @return array
 */
 function heap_sort(array $lists)
 {
 $n = count($lists);
 build_heap($lists);
 while (--$n) {
 $val = $lists[0];
 $lists[0] = $lists[$n];
 $lists[$n] = $val;
 heap_adjust($lists, 0, $n);
 //echo "sort: " . $n . "\t" . implode(', ', $lists) . PHP_EOL;
 }
 return $lists;
 } 
function build_heap(array &$lists)
 {
 $n = count($lists) - 1;
 for ($i = floor(($n - 1) / 2); $i >= 0; $i--) {
 heap_adjust($lists, $i, $n + 1);
 //echo "build: " . $i . "\t" . implode(', ', $lists) . PHP_EOL;
 }
 //echo "build ok: " . implode(', ', $lists) . PHP_EOL;
 }

 function heap_adjust(array &$lists, $i, $num)
 {
 if ($i > $num / 2) {
 return;
 }
 $key = $i;
 $leftChild = $i * 2 + 1;
 $rightChild = $i * 2 + 2;
 
 if ($leftChild < $num && $lists[$leftChild] > $lists[$key]) {
 $key = $leftChild;
 }
 if ($rightChild < $num && $lists[$rightChild] > $lists[$key]) {
 $key = $rightChild;
 }
 if ($key != $i) {
 $val = $lists[$i];
 $lists[$i] = $lists[$key];
 $lists[$key] = $val;
 heap_adjust($lists, $key, $num);
 }
 }

7 hill sort

Hill sort, also known as decreasing incremental sort algorithm, is a more efficient improved version of insertion sort.

But Hill sorting is an unstable sorting algorithm.

Hill sort is an improved method based on the following two properties of insertion sort:

Insertion sorting is efficient when operating on almost ordered data, that is, it can achieve the efficiency of linear sorting

But insert sort is generally inefficient because insert sort can only move data one bit at a time

Algorithm steps:

Firstly, the whole record sequence to be sorted is divided into several subsequences for direct insertion sorting

When the records in the whole sequence are “basically in order”, all records are directly inserted and sorted in turn.

PHP implementation code:

/**
 *Hill sort criteria
 *
 * @param array $lists
 * @return array
 */
 function shell_sort(array $lists)
 {
 $n = count($lists);
 $step = 2;
 $gap = intval($n / $step);
 while ($gap > 0) {
 for ($gi = 0; $gi < $gap; $gi++) {
 for ($i = $gi; $i < $n; $i += $gap) {
 $key = $lists[$i];
 for ($j = $i - $gap; $j >= 0 && $lists[$j] > $key; $j -= $gap) {
 $lists[$j + $gap] = $lists[$j];
 $lists[$j] = $key;
 }
 }
 }
 $gap = intval($gap / $step);
 }
 return $lists;
 }

8 cardinality sorting

Radix sorting is a non comparative integer sorting algorithm. Its principle is to cut integers into different numbers according to the number of bits, and then compare them according to each number of bits.

Since integers can also express strings (such as names or dates) and floating-point numbers in a specific format, cardinality sorting is not limited to integers.

Before talking about cardinality sorting, let’s briefly introduce bucket sorting:

Bucket sorting is to divide the array into a limited number of buckets.

Each bucket is sorted individually. It is possible to use another sorting algorithm, or continue to use bucket sorting in a recursive manner.

Bucket sorting is an inductive result of pigeon nest sorting.

When the values in the array to be sorted are evenly distributed, bucket sorting uses linear time o (n).

However, bucket sorting is not a comparative sorting. It is not affected by the lower limit of O (n log n).

Simply put, it is to group the data into buckets, and then sort the data in each bucket.

For example, to sort n integers a [1.. n] in the range of size [1.. 1000]

First, the bucket can be set to a range of size 10. Specifically, set B [1] to store integers of [1.. 10], set B [2] to store integers of (10.. 20),… Set B [i] to store integers of ((i-1) * 10, I * 10]), I = 1,2,… 100. There are 100 barrels in total.

Then, scan a [1.. n] from beginning to end, and put each a [i] into the corresponding bucket B [J]. Then sort the numbers in each of the 100 buckets. At this time, you can bubble, select, and even arrange quickly. Generally speaking, any sorting method can be used.

Finally, the numbers in each bucket are output in turn, and the numbers in each bucket are output from small to large, so as to get a sequence in which all the numbers are arranged in order.

Suppose there are n numbers and M buckets. If the numbers are evenly distributed, there are n / M numbers in each bucket.

If the numbers in each bucket are sorted quickly, the complexity of the whole algorithm is

O(n + m * n/m*log(n/m)) = O(n + nlogn – nlogm)

It can be seen from the above formula that when m is close to N, the bucket sorting complexity is close to o (n)

Of course, the calculation of the above complexity is based on the assumption that the input n numbers are evenly distributed. This assumption is very strong, and the effect is not so good in practical application. If all the numbers fall into the same bucket, it will degenerate into a general sort.

The time complexity of most sorting algorithms is N2 (NLO). Bucket sorting can achieve o (n) time complexity. However, the disadvantages of bucket sorting are:

1) Firstly, the space complexity is relatively high and the additional overhead is large. Sorting has the space overhead of two arrays, one is to store the array to be sorted, and the other is the so-called bucket. For example, if the value to be sorted is from 0 to M-1, m buckets are required, and this bucket array needs at least m spaces.

2) Secondly, the elements to be sorted must be within a certain range, and so on.

/**
 *Cardinality sort
 *
 * @param array $lists
 * @return array
 */
 function radix_sort(array $lists)
 {
 $radix = 10;
 $max = max($lists);
 $k = ceil(log($max, $radix));
 if ($max == pow($radix, $k)) {
 $k++;
 }
 for ($i = 1; $i <= $k; $i++) {
 $newLists = array_fill(0, $radix, []);
 for ($j = 0; $j < count($lists); $j++) {
 $key = $lists[$j] / pow($radix, $i - 1) % $radix;
 $newLists[$key][] = $lists[$j];
 }
 $lists = [];
 for ($j = 0; $j < $radix; $j++) {
 $lists = array_merge($lists, $newLists[$j]);
 }
 }
 return $lists;
 }

9 summary

The stability, time complexity, space complexity and stability of various sorts are summarized in the figure below:

About time complexity:

(1) Square order (O (N2)) sorting

Various simple sorting: direct insertion, direct selection and bubble sorting;

(2) Linear logarithmic order (O (nlog2n)) sort

Quick sort, heap sort and merge sort;

(3) O (N1 + §) sort, § is a constant between 0 and 1.

Shell Sort

(4) Linear order (O (n)) sorting

Cardinality sorting, as well as bucket and box sorting.

About stability:

Stable sorting algorithms: bubble sort, insert sort, merge sort and cardinal sort

It is not a stable sorting algorithm: selective sorting, quick sorting, Hill sorting and heap sorting

summary

The above is a commonly used sorting algorithm for PHP implementation introduced by Xiaobian. I hope it will be helpful to you!

Recommended Today

Implementation example of go operation etcd

etcdIt is an open-source, distributed key value pair data storage system, which provides shared configuration, service registration and discovery. This paper mainly introduces the installation and use of etcd. Etcdetcd introduction etcdIt is an open source and highly available distributed key value storage system developed with go language, which can be used to configure sharing […]