PHP中的数组排序算法
用PHP对数组进行排序的方法有很多,最简单的方法就是使用sort()PHP内置的函数。这种排序功能虽然很快,但却有其局限性,尤其是在对日期等内容进行排序时,因为PHP通常会猜测哪个值比另一个更高,并且会产生奇怪的结果。但是,有许多可用的排序算法,无法让您以所需的任何方式对数组进行排序。
其中最简单的方法称为冒泡排序。这是一个将使用冒泡排序算法对值数组进行排序的函数。
function bubbleSort($array) { if (!$length = count($array)) { return $array; } for ($outer = 0; $outer < $length; $outer++) { for ($inner = 0; $inner < $length; $inner++) { if ($array[$outer] < $array[$inner]) { $tmp = $array[$outer]; $array[$outer] = $array[$inner]; $array[$inner] = $tmp; } } } }
该算法通过遍历数组并为下一个值交换一个值(如果该值小于当前值)来工作。第一次运行后,数组中的最大值将位于正确的末端。因此,它必须为数组中的每个项目在数组中运行一次,因此效率很低。
双向气泡排序是对此的一种改进,其中,项目同时运行两次,一个从上到下,另一个从下到上。以下代码是双向气泡排序示例,具有更高的效率。此函数假定在遍历数组一次后,第一个和最后一个元素位于正确的位置。因此,它将查看减去这两个值的数组。
function bidirectionalBubbleSort($array){ if(!$length = count($array)){ return $array; } $start = -1; while($start < $length){ ++$start; --$length; for($i= $start; $i < $length; ++$i){ if($array[$i] > $array[$i + 1]){ $temp = $array[$i]; $array[$i] = $array[$i + 1]; $array[$i + 1] = $temp; } } for($i = $length; --$i >= $start;){ if($array[$i] > $array[$i + 1]){ $temp = $array[$i]; $array[$i] = $array[$i + 1]; $array[$i + 1] = $temp; } } } }
但是,这仍然不是那么有效。为了获得更高的效率,您需要使用短外壳。这适用于“分而治之”的技术,在该技术中可以查看数组的各个组并分别对其进行排序。这是一个示例函数。
function shellSort($array) { if (!$length = count($array)) { return $array; } $k = 0; $gap[0] = (int)($length/2); while($gap[$k]>1){ $k++; $gap[$k] = (int)($gap[$k-1]/2); } for ($i = 0; $i <= $k; $i++) { $step = $gap[$i]; for ($j = $step; $j<$length; $j++) { $temp = $array[$j]; $p = $j-$step; while ($p >= 0 && $temp < $array[$p]) { $array[$p+$step] = $array[$p]; $p = $p-$step; } $array[$p+$step] = $temp; } } return $array; }
尽管这看起来效率不高,但这取决于您要排序的数据。在最佳情况下,数据将被随机放置在整个阵列中,因此该算法将具有良好的效率。最糟糕的情况是,在尝试对所有数据进行排序之前,它们都按错误的方向排序。但是,除非您确信所有情况下都会发生最坏的情况,否则值得使用此功能。对随机数数组的测试表明,与冒泡排序相比,该算法是不错的选择。
我应该在这里提到另一种称为快速排序的算法。该函数通过将数组分成越来越小的块,最后在最后将数组重新合并在一起而起作用。为此,首先要找到一个中间点,然后根据当前值是高于还是低于中间值来分割数组。然后,它以递归方式调用自身,以便对数组的每个部分进行相同的操作。这是一个快速排序的示例:
function quickSort($array) { if (!$length = count($array)) { return $array; } $k = $array[0]; $x = $y = array(); for ($i=1;$i<$length;$i++) { if ($array[$i] <= $k) { $x[] = $array[$i]; } else { $y[] = $array[$i]; } } return array_merge(quickSort($x),array($k),quickSort($y)); }
顾名思义,这是一种快速的排序方式,而如果我们不使用PHP,那将是一种排序方式。尽管此功能在Java或C中非常快,但在PHP中却非常慢。这是因为PHP不能很好地处理递归。实际上,在尝试测试此功能时,它要么使脚本超时,要么只是给出以下内存错误。
Fatalerror:Allowedmemorysizeof134217728bytesexhausted(triedtoallocate35bytes)inC:\htdocs\test.phponline130
这种情况在测试长度仅为50的数组时发生,并且是因为每次PHP递归调用函数时,都会将该信息添加到调用堆栈中。发生此错误是因为该堆栈已满。因此,尽管快速排序在其他语言中速度很快,但您可能应该坚持使用shell排序或类似的方法。至少您将需要使用不使用递归的函数。
如果您想编写自己的排序功能,则可以使用以下功能检查您的工作。
function checkSort($array) { if (!$length = count($array)) { return true; } for ($i = 0; $i < $length; $i++) { if (isset($array[$i+1])) { if ($array[$i]>$array[$i+1]) { return false; } } } return true; }
您可以使用PHP基准测试功能测试算法运行多长时间。