搜索
首页后端开发php教程php实现几种常见的排序算法

php实现几种常见的排序算法

Mar 10, 2018 pm 01:34 PM
php排序算法

交换排序:交换排序的基本思想是,比较两个记录键值的大小,如果这两个记录键值的大小出现逆序,则交换这两个记录,这样将键值较小的记录向序列前部移动,键值较大的记录向序列后部移动。




一、冒泡排序        

介绍:

冒泡排序(Bubble Sort,台湾译为:泡沫排序或气泡排序)是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。

步骤:

  1. 比较相邻的元素。如果第一个比第二个大,就交换他们两个。

  2. 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。

  3. 针对所有的元素重复以上的步骤,除了最后一个。

  4. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

冒泡排序理解起来是最简单,但是时间复杂度(O(n^2))也是最大的之一,实现代码如下:

<br/>
  1. $arr=array(1,43,54,62,21,66,32,78,36,76,39);    

  2. function getpao($arr)  

  3. {    

  4.   $len=count($arr);  

  5.   //设置一个空数组 用来接收冒出来的泡  

  6.   //该层循环控制 需要冒泡的轮数  

  7.   for($i=1;$ifce73b07cbaf6ec81d000bb4356e24b2$arr[$k+1])  

  8.         {  

  9.             $tmp=$arr[$k+1];  

  10.             $arr[$k+1]=$arr[$k];  

  11.             $arr[$k]=$tmp;  

  12.         }  

  13.     }  

  14.   }  

  15.   return $arr;  

  16. }   

二、快速排序 

介绍:

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

步骤:

  1. 从数列中挑出一个元素,称为 “基准”(pivot),

  2. 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。

  3. 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。

快排也是一个高效的排序算法,它的时间复杂度也是O(nlogn)。代码如下:

  1. function quick_sort($arr) {  

  2.     //先判断是否需要继续进行  

  3.     $length = count($arr);  

  4.     if($length 03bfaf23b6993910faec2986d34f455c $arr[$i]) {  

  5.             //放入左边数组  

  6.             $left_array[] = $arr[$i];  

  7.         } else {  

  8.             //放入右边  

  9.             $right_array[] = $arr[$i];  

  10.         }  

  11.     }  

  12.     //再分别对 左边 和 右边的数组进行相同的排序处理方式  

  13.     //递归调用这个函数,并记录结果  

  14.     $left_array = quick_sort($left_array);  

  15.     $right_array = quick_sort($right_array);  

  16.     //合并左边 标尺 右边  

  17.     return array_merge($left_arrayarray($base_num), $right_array);  

  18. }  

选择排序

       选择排序包括两种,分别是直接选择排序和堆排序,选择排序的基本思想是每一次在n-i+1(i=1,2,3,...,n-1)个记录中选取键值最小的记录作为有序序列的第i个记录

三、选择排序 

介绍:

选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理如下。首先在未排序序列中找到最小元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小元素,然后放到排序序列末尾。以此类推,直到所有元素均排序完毕。


选择排序理解起来也比较简单,时间复杂度也是O(n^2),实现代码如下:

<br/>


[php] view plain copy


  1. function select_sort($arr) {  

  2. //实现思路 双重循环完成,外层控制轮数,当前的最小值。内层 控制的比较次数  

  3.     //$i 当前最小值的位置, 需要参与比较的元素  

  4.     for($i=0, $len=count($arr); $ia580c4c724e858b47f065997c15bf495 $arr[$j]) {  

  5.      //比较,发现更小的,记录下最小值的位置;并且在下次比较时,  

  6.  // 应该采用已知的最小值进行比较。  

  7.                 $p = $j;  

  8.             }  

  9.         }  

  10.         //已经确定了当前的最小值的位置,保存到$p中。  

  11.  //如果发现 最小值的位置与当前假设的位置$i不同,则位置互换即可  

  12.         if($p != $i) {  

  13.             $tmp = $arr[$p];  

  14.             $arr[$p] = $arr[$i];  

  15.             $arr[$i] = $tmp;  

  16.         }  

  17.     }  

  18.     //返回最终结果  

  19.     return $arr;  

  20. }  

四、堆排序 

介绍:

堆积排序(Heapsort)是指利用这种数据结构所设计的一种排序算法。堆是一个近似完全二叉树的结构,并同时满足堆性质:即子结点的键值或索引总是小于(或者大于)它的父节点。

步骤:

堆排序是指利用堆积树(堆)这种数据结构所设计的一种排序算法,利用数组的特点快速定位指定索引的元素。堆分为大根堆和小根堆,是完全二叉树。大根堆的要求是每个节点的值都不大于其父节点的值,即A[PARENT[i]] >= A[i]。在数组的非降序排序中,需要使用的就是大根堆,因为根据大根堆的要求可知,最大的值一定在堆顶。

排序效果:


堆排序是一种高效的排序算法,它的时间复杂度是O(nlogn)。原理是:先把数组转为一个最大堆,然后把第一个元素跟第i元素交换,然后把剩下的i-1个元素转为最大堆,然后再把第一个元素与第i-1个元素交换,以此类推。实现代码如下:

function heapSort($arr) {
    $len = count($arr);    // 先建立最大堆
    for ($i = floor(($len - 1) / 2); $i >= 0; $i--) {        $s = $i;        $childIndex = $s * 2 + 1;        while ($childIndex < $len) {            // 在父、左子、右子中 ,找到最大的
            if ($childIndex + 1 < $len && $arr[$childIndex] < $arr[$childIndex + 1]) $childIndex++;            if ($arr[$s] < $arr[$childIndex]) {                $t = $arr[$s];                $arr[$s] = $arr[$childIndex];                $arr[$childIndex] = $t;                $s = $childIndex;                $childIndex = $childIndex * 2 + 1;
            } else {                break;
            }
        }
    }    // 从最后一个元素开始调整
    for ($i = $len - 1; $i > 0; $i--) {        $t = $arr[$i];        $arr[$i] = $arr[0];        $arr[0] = $t;        // 调整第一个元素
        $s = 0;        $childIndex = 1;        while ($childIndex < $i) {            // 在父、左子、右子中 ,找到最大的
            if ($childIndex + 1 < $i && $arr[$childIndex] < $arr[$childIndex + 1]) $childIndex++;            if ($arr[$s] < $arr[$childIndex]) {                $t = $arr[$s];                $arr[$s] = $arr[$childIndex];                $arr[$childIndex] = $t;                $s = $childIndex;                $childIndex = $childIndex * 2 + 1;
            } else {                break;
            }
        }
    }    return $arr;
}$arr = [3,1,13,5,7,11,2,4,14,9,15,6,12,10,8];
print_r(bubbleSort($arr));


插入排序 

五、插入排序 

介绍:

插入排序(Insertion Sort)的算法描述是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,通常采用in-place排序(即只需用到O(1)的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。

步骤:

  1. 从第一个元素开始,该元素可以认为已经被排序

  2. 取出下一个元素,在已经排序的元素序列中从后向前扫描

  3. 如果该元素(已排序)大于新元素,将该元素移到下一位置

  4. 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置

  5. 将新元素插入到该位置中

  6. 重复步骤2


感觉插入排序跟冒泡排序有点相似,时间复杂度也是O(n^2),实现代码如下:


[php] view plain copy


  1. function insert_sort($arr) {  

  2.     //区分 哪部分是已经排序好的  

  3.     //哪部分是没有排序的  

  4.     //找到其中一个需要排序的元素  

  5.     //这个元素 就是从第二个元素开始,到最后一个元素都是这个需要排序的元素  

  6.     //利用循环就可以标志出来  

  7.     //i循环控制 每次需要插入的元素,一旦需要插入的元素控制好了,  

  8.     //间接已经将数组分成了2部分,下标小于当前的(左边的),是排序好的序列  

  9.     for($i=1, $len=count($arr); $i62e79953781169d2df00f16d4e233ba3=0;$j--) {  

  10.    //$arr[$i];//需要插入的元素; $arr[$j];//需要比较的元素  

  11.             if($tmp 50cb06c677d0db5577777f06e22e5f03

    排序效果:


    希尔排序其实可以理解是插入排序的一个优化版,它的效率跟增量有关,增量要取多少,根据不同的数组是不同的,所以希尔排序是一个不稳定的排序算法,它的时间复杂度为O(nlogn)到O(n^2)之间,实现代码如下:

    function shellSort($arr) {
        $len = count($arr);    $stepSize = floor($len / 2);    while ($stepSize >= 1) {        for ($i = $stepSize; $i < $len; $i++) {            if ($arr[$i] < $arr[$i - $stepSize]) {                $t = $arr[$i];                $j = $i - $stepSize;                while ($j >= 0 && $t < $arr[$j]) {                    $arr[$j + $stepSize] = $arr[$j];                    $j -= $stepSize;
                    }                $arr[$j + $stepSize] = $t;
                }
            }        // 缩小步长,再进行插入排序
            $stepSize = floor($stepSize / 2);
        }    return $arr;
    }$arr = [3,1,13,5,7,11,2,4,14,9,15,6,12,10,8];
    print_r(bubbleSort($arr));


    七、归并排序 

    介绍:

    归并排序(Merge sort,台湾译作:合并排序)是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(pide and Conquer)的一个非常典型的应用

    步骤:

    1. 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列

    2. 设定两个指针,最初位置分别为两个已经排序序列的起始位置

    3. 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置

    4. 重复步骤3直到某一指针达到序列尾

    5. 将另一序列剩下的所有元素直接复制到合并序列尾

    排序效果:


    归并排序的时间复杂度也是O(nlogn)。原理是:对于两个排序好的数组,分别遍历这两个数组,获取较小的元素插入新的数组中,那么,这么新的数组也会是排序好的。代码如下:

    我们先来看看主函数部分:

    //交换函数function swap(array &$arr,$a,$b){
        $temp = $arr[$a];    $arr[$a] = $arr[$b];    $arr[$b] = $temp;
    }//归并算法总函数function MergeSort(array &$arr){
        $start = 0;    $end = count($arr) - 1;
        MSort($arr,$start,$end);
    }

    在总函数中,我们只调用了一个 MSort() 函数,因为我们要使用递归调用,所以将 MSort() 封装起来。

    下面我们来看看 MSort() 函数:

    function MSort(array &$arr,$start,$end){    //当子序列长度为1时,$start == $end,不用再分组    if($start < $end){        $mid = floor(($start + $end) / 2);	//将 $arr 平分为 $arr[$start - $mid] 和 $arr[$mid+1 - $end]        MSort($arr,$start,$mid);			//将 $arr[$start - $mid] 归并为有序的$arr[$start - $mid]        MSort($arr,$mid + 1,$end);			//将 $arr[$mid+1 - $end] 归并为有序的 $arr[$mid+1 - $end]        Merge($arr,$start,$mid,$end);       //将$arr[$start - $mid]部分和$arr[$mid+1 - $end]部分合并起来成为有序的$arr[$start - $end]
        }
    }

    上面的 MSort() 函数实现将数组分半再分半(直到子序列长度为1),然后将子序列合并起来。

    现在是我们的归并操作函数 Merge() :

    //归并操作function Merge(array &$arr,$start,$mid,$end){
        $i = $start;    $j=$mid + 1;    $k = $start;    $temparr = array();    while($i!=$mid+1 && $j!=$end+1)
        {       if($arr[$i] >= $arr[$j]){           $temparr[$k++] = $arr[$j++];
           }       else{           $temparr[$k++] = $arr[$i++];
           }
        }    //将第一个子序列的剩余部分添加到已经排好序的 $temparr 数组中
        while($i != $mid+1){        $temparr[$k++] = $arr[$i++];
        }    //将第二个子序列的剩余部分添加到已经排好序的 $temparr 数组中
        while($j != $end+1){        $temparr[$k++] = $arr[$j++];
        }    for($i=$start; $i<=$end; $i++){        $arr[$i] = $temparr[$i];
        }
    }

    到了这里,我们的归并算法就完了。我们调用试试:

    $arr = array(9,1,5,8,3,7,4,6,2);
    MergeSort($arr);
    var_dump($arr);

    相关推荐:

    php冒泡、选择、插入和快速排序算法分享

    PHP多维数组排序算法分析

    PHP排序算法系列之直接选择排序详解

以上是php实现几种常见的排序算法的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
解释负载平衡如何影响会话管理以及如何解决。解释负载平衡如何影响会话管理以及如何解决。Apr 29, 2025 am 12:42 AM

负载均衡会影响会话管理,但可以通过会话复制、会话粘性和集中式会话存储解决。1.会话复制在服务器间复制会话数据。2.会话粘性将用户请求定向到同一服务器。3.集中式会话存储使用独立服务器如Redis存储会话数据,确保数据共享。

说明会话锁定的概念。说明会话锁定的概念。Apr 29, 2025 am 12:39 AM

Sessionlockingisatechniqueusedtoensureauser'ssessionremainsexclusivetooneuseratatime.Itiscrucialforpreventingdatacorruptionandsecuritybreachesinmulti-userapplications.Sessionlockingisimplementedusingserver-sidelockingmechanisms,suchasReentrantLockinJ

有其他PHP会议的选择吗?有其他PHP会议的选择吗?Apr 29, 2025 am 12:36 AM

PHP会话的替代方案包括Cookies、Token-basedAuthentication、Database-basedSessions和Redis/Memcached。1.Cookies通过在客户端存储数据来管理会话,简单但安全性低。2.Token-basedAuthentication使用令牌验证用户,安全性高但需额外逻辑。3.Database-basedSessions将数据存储在数据库中,扩展性好但可能影响性能。4.Redis/Memcached使用分布式缓存提高性能和扩展性,但需额外配

在PHP的上下文中定义'会话劫持”一词。在PHP的上下文中定义'会话劫持”一词。Apr 29, 2025 am 12:33 AM

Sessionhijacking是指攻击者通过获取用户的sessionID来冒充用户。防范方法包括:1)使用HTTPS加密通信;2)验证sessionID的来源;3)使用安全的sessionID生成算法;4)定期更新sessionID。

PHP的完整形式是什么?PHP的完整形式是什么?Apr 28, 2025 pm 04:58 PM

文章讨论了PHP,详细介绍了其完整形式,在We​​b开发中的主要用途,与Python和Java的比较以及对初学者的学习便利性。

PHP如何处理形式数据?PHP如何处理形式数据?Apr 28, 2025 pm 04:57 PM

PHP使用$ \ _ post和$ \ _获取超级全局的php处理数据,并通过验证,消毒和安全数据库交互确保安全性。

PHP和ASP.NET有什么区别?PHP和ASP.NET有什么区别?Apr 28, 2025 pm 04:56 PM

本文比较了PHP和ASP.NET,重点是它们对大规模Web应用程序,性能差异和安全功能的适用性。两者对于大型项目都是可行的,但是PHP是开源和无关的,而ASP.NET,

PHP是对病例敏感的语言吗?PHP是对病例敏感的语言吗?Apr 28, 2025 pm 04:55 PM

PHP的情况敏感性各不相同:功能不敏感,而变量和类是敏感的。最佳实践包括一致的命名和使用对案例不敏感的功能进行比较。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

WebStorm Mac版

WebStorm Mac版

好用的JavaScript开发工具

MinGW - 适用于 Windows 的极简 GNU

MinGW - 适用于 Windows 的极简 GNU

这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )专业的PHP集成开发工具