美文网首页
PHP实现常见的排序算法

PHP实现常见的排序算法

作者: tscgo_cn | 来源:发表于2020-12-31 23:52 被阅读0次
在PHP中已经有现成的函数帮助我们为数组排序,那我们还有必要去自己实现为数组排序的算法吗?有的。我们知道其实 程序 = 数据结构 + 算法,可见算法在我们程序中是非常关键的组成部分,好的算法可以让程序的执行效率更高,占用空间更少。
举个例子,我们写一个计算1+2+3+4+……+999+1000的程序,方法1我们可以先计算1+2 = 3,然后计算3+3 = 6,然后计算6+4 = 10 ,然后 10+5 =15 …… 计算999次,最后得到结果。方法2我们可以使用中学学过的等差数列求和公式Sn=n(a1+an)/2 , 直接计算1000 * (1+1000)/ 2 得到结果,使用方法2的程序只需计算1次,就能得到结果,所以效率更高。这就是算法的作用和魅力所在。
下面我们通过排序算法了解计算机是怎么为我们的数组排序的,去入门算法。

注:为方便描述,下面的排序全为正序(从小到大排序)

一、冒泡排序

假设有一个数组[a,b,c,d]
冒泡排序依次比较相邻的两个元素,如果前面的元素大于后面的元素,则两元素交换位置;否则,位置不变。具体步骤:
1,比较a,b这两个元素,如果a>b,则交换位置,数组变为:[b,a,c,d]
2,比较a,c这两个元素,如果a<c,则位置不变,数组变为:[b,a,c,d]
3,比较c,d这两个元素,如果c>d,则交换位置,数组变为:[b,a,d,c]
完成第一轮比较后,可以发现最大的数c已经排(冒)在最后面了,接着再进行第二轮比较,但第二轮比较不必比较最后一个元素了,因为最后一个元素已经是最大的了。
第二轮比较结束后,第二大的数也会冒到倒数第二的位置。
依次类推,再进行第三轮,,,
就这样最大的数一直往后排(冒),最后完成排序。所以我们称这种排序算法为冒泡排序。

$arr = [9,4,7,1,8,6,3,10,2];
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;
}

$arr = bubbleSort($arr);
print_r($arr);
冒泡排序.gif

二、选择排序

选择排序是一种直观的算法,每一轮会选出列中最小的值,把最小值排到前面。具体步骤如下:

  1. 第一轮,先把数组中的第一个元素作为最小值,最小值的位置(索引)保存在一个变量$min中
  2. 接着拿第二个元素与我们初始设定的最小值比较,如果第二个元素比最小值小,那么$min的值变为第二个元素的位置(索引),否则,不做处理。
  3. 接着同样的去拿最新的最小值与第三个元素比较,与第四个,第五个,,,到最后,这得到的$min就是数组中的最小值, 然后把最小值与第一个元素交换位置,至此,第一轮循环结束。
    4,用同样的方法进行第二轮查找,找到第二个最小值,与第二个元素交换位置;然后第三个,第四个,直至排序完成
$arr = [9,4,7,1,8,6,3,10,2];
//实现思路 双重循环完成,外层控制轮数,当前的最小值。内层控制比较次数
function selectSort($arr) {
    $len = count($arr);

    //$i 当前最小值的位置, 需要参与比较的元素
    for ($i = 0; $i < $len - 1; $i++) {
        //先假设最小的值的位置
        $min = $i;
        //所以$arr[$min] 是 当前已知的最小值

        //$j 当前都需要和哪些元素比较,$i 后边的。
        for ($j = $i + 1; $j < $len; $j++) {
            //比较,发现更小的,记录下最小值的位置;并且在下次比较时,应该采用已知的最小值进行比较。
            $min = ($arr[$min] <= $arr[$j]) ? $min : $j;
        }

        //已经确定了当前的最小值的位置,保存到$min中。
        //如果发现 最小值的位置与当前假设的位置$i不同,则位置互换即可
        if ($min != $i) {
            $tmp     = $arr[$min];
            $arr[$min] = $arr[$i];
            $arr[$i] = $tmp;
        }
    }
    return $arr;
}

$arr = selectSort($arr);
print_r($arr);
选择排序.gif

三、插入排序

插入排序步骤大致如下:

  1. 先定义第一个元素为有序数列,第二个元素与第一个元素相比,如果第二元素小于第一个元素,则把第二个元素插到第一个元素的前面,否则,顺序不变。如此,第一个元素和第二个元素就组成了一个新的有序数列
  2. 第三个元素与前面所述的有序数列比较,如果第三个元素小于第二个元素,则第三个元素再与第一个元素比较,如果第三个元素大于第一个元素,那么第三个元素就插入到第一二元素中间,此时有序数列变成了三个元素。
  3. 如此重复,进行第四个,第五个,第六个,,,元素到排序
//插入排序
$arr = [9,4,7,1,8,6,3,10,2];
function insertSort($arr)
{
   $len=count($arr);
   for($i=1; $i<$len; $i++) {
       //获得当前需要比较的元素值
       $tmp = $arr[$i];
       //内层循环控制 比较 并 插入
       for($j=$i-1; $j>=0; $j--) {
           //$arr[$i];需要插入的元素
           //$arr[$j];需要比较的元素
           if($tmp < $arr[$j])
           {
               //发现插入的元素要小,交换位置
               //将后边的元素与前面的元素互换
               $arr[$j+1] = $arr[$j];

               //将前面的数设置为 当前需要交换的数
               $arr[$j] = $tmp;
           } else {
               //如果碰到不需要移动的元素
               //由于是已经排序好是数组,则前面的就不需要再次比较了。
               break;
           }
       }
   }
   //将这个元素 插入到已经排序好的序列内。
   //返回
   return $arr;
}

$arr = insertSort($arr);
print_r($arr);

插入排序.gif

四、快速排序

快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要Ο(n log n)次比较。在最坏状况下则需要Ο(n2)次比较,但这种状况并不常见。事实上,快速排序通常明显比其他Ο(n log n) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来,且在大部分真实世界的数据,可以决定设计的选择,减少所需时间的二次方项之可能性。

步骤:
从数列中挑出一个元素,称为 “基准”(pivot),
重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。

//快速排序
$arr = [9,4,7,1,8,6,3,10,2];
function quickSort($arr)
{
    //判断参数是否是一个数组
    if(!is_array($arr)) return false;

    //递归出口:数组长度为1,直接返回数组
    $length = count($arr);

    if($length<=1) return $arr;

    //数组元素有多个,则定义两个空数组
    $left = $right = array();

    //使用for循环进行遍历,把第一个元素当做比较的对象
    for($i=1; $i<$length; $i++)
    {
        //判断当前元素的大小
        if($arr[$i] < $arr[0]){  //从小到大 < || 从大到小 >
            $left[]=$arr[$i];
        }else{
            $right[]=$arr[$i];
        }
    }

    //递归调用
    $left=quickSort($left);
    $right=quickSort($right);

    //将所有的结果合并
    return array_merge($left,array($arr[0]),$right);
}

$arr = quickSort($arr);
print_r($arr);
快速排序.gif

相关文章

  • PHP实现常见的排序算法

    在PHP中已经有现成的函数帮助我们为数组排序,那我们还有必要去自己实现为数组排序的算法吗?有的。我们知道其实 程序...

  • 常用的排序算法

    常用的排序算法(PHP实现)_慕课手记

  • 排序算法

    常见排序算法比较 参考资料:各种排序算法比较 参考资料:快速排序算法 必须知道的八大种排序算法【java实现】(一...

  • 插入排序算法实现

    排序算法是最常见,最基础的算法,作者文集中记录了两种排序算法(插入排序,归并排序) 插入排序算法实现很简单直接,附...

  • 0.PHP面试都问什么

    PHP基础语法知识PHP底层原理常见的算法实现MysqlRedisHTTP原理fast-cgi常见的Linux命令...

  • 编程算法之排序和查找算法

    查找和排序算法是算法的入门知识,其经典思想可以用于很多算法当中。因为其实现代码较短,应用较常见。 一. 排序 常见...

  • PHP常见排序算法

    1:冒泡排序 排序思路:在要排序的一组数中,对当前还未排好的序列,从前往后对相邻的两个数依次进行比较和调整,让较大...

  • 排序与搜索

    排序算法: 一种能将一串数据依照特定顺序进行排列的一种算法 常见排序算法效率的比较 排序算法的实现 1. 冒泡排序...

  • 7大经典的排序算法总结实现

    作者 : 专注J2EE来源 : 博客园 常见排序算法总结与实现 本文使用Java实现这几种排序。以下是对排序算法总...

  • 【非比较类排序算法】计数排序、桶排序(PHP实现)

    常见的经典非比较类排序算法有计数排序、桶排序。区别于比较类排序,非比较类排序利用额外的内存空间实现更快排序,算法以...

网友评论

      本文标题:PHP实现常见的排序算法

      本文链接:https://www.haomeiwen.com/subject/fbfgnktx.html