php实现归并排序算法的方法详解

目录
  • php实现归并排序算法
    • 归并排序原理
  • 总结

php实现归并排序算法

归并排序算法的复杂度是O(nlogn)。

代码如下,只需要clone下来执行composer install然后执行 php artisan test:mergeSort 就可以看到结果了

    /**
     * 归并排序把数据逐步分解,然后对分解后的数据进行排序,最后合并到一起
     *
     * @return mixed
     */
    public function handle()
    {
        $this->a = [3,70,4,38,5,6,8,4,7,10,6,10,34,4];
        dump($this->a);
        $a = $this->mergeSort($this->a, 0, count($this->a));
        dd($a);
    }
    private function mergeSort($a, $lo, $hi) {
        if (($hi - $lo) < 2) return [$a[$lo]];
        $mi = ($lo + $hi) >> 1;
        //把中点左边的进行归并
        $b = $this->mergeSort($a, $lo, $mi);
        dump('$b:',$b);
        //把中点右边的进行归并
        $c = $this->mergeSort($a, $mi, $hi);
        dump('$c:',$c);
        //把所有数据进行排序
        return $this->merge($b, $c, $lo,$mi,$hi);
    }
    /**
     * 假设有一个数组$a分成了两个数组[3,4] [2,8]
     * 逐一比较,3and2,取出来2然后3and8取出来3然后4and8取出来4,最后取出来8
     *
     * @param [type] $lo
     * @param [type] $mi
     * @param [type] $hi
     * @return void
     */
    private function merge($b, $c, $lo, $mi, $hi) {
        $lb = $mi - $lo; //$b数组的边界
        $lc = $hi - $mi; //$c数组的边界
        $res = [];
        //$i表示合并后数组的下标 $ib是b数组的下标 $ic是c数组的下标
        for($i = 0,$ib=0,$ic=0;$ib<$lb || $ic < $lc;){
            //ib 下标没有越界 && c的数组已经空了也就是$ic >= $lc || 比较两个数组首位的大小 如果b的首元素 < c的首元素,那么取出来b的首元素
            if ($ib < $lb && ( $ic >= $lc || $b[$ib] <= $c[$ic])) {
                $res[$i++] = $b[$ib++];
            }
            //k 下标没有越界 && b的数组已经空了也就是$ib >= $lb || 如果c的首元素 < b的首元素,那么取出来c的首元素
            if ($ic < $lc && ($ib >= $lb || $b[$ib] > $c[$ic])) {
                $res[$i++] = $c[$ic++];
            }
        }
        return $res;
    }

归并排序原理

归并排序和快排刚好相反,是先将整个数组左右打散,然后在逐一合并进行排序,最终完成整个数组的排序,排序示意图如下:

首先将整个数组左右打散,变成单个元素,因为单个元素可以被认为是有序的。

对应代码

if (($hi - $lo) < 2) return [$a[$lo]];
$mi = ($lo + $hi) >> 1;
//把中点左边的进行归并
$b = $this->mergeSort($a, $lo, $mi);
dump('$b:',$b);
//把中点右边的进行归并
$c = $this->mergeSort($a, $mi, $hi);
dump('$c:',$c);

接下来对左右两个有序数组进行排序,假设有一个数组$a分成了两个数组[3,4] [2,8],逐一比较,3and2,取出来2然后3and8取出来3然后4and8取出来4,最后取出来8,对应代码:

$lb = $mi - $lo; //$b数组的边界
$lc = $hi - $mi; //$c数组的边界
$res = [];
//$i表示合并后数组的下标 $ib是b数组的下标 $ic是c数组的下标
for($i = 0,$ib=0,$ic=0;$ib<$lb || $ic < $lc;){
    //ib 下标没有越界 && c的数组已经空了也就是$ic >= $lc || 比较两个数组首位的大小 如果b的首元素 < c的首元素,那么取出来b的首元素
    if ($ib < $lb && ( $ic >= $lc || $b[$ib] <= $c[$ic])) {
        $res[$i++] = $b[$ib++];
    }
    //k 下标没有越界 && b的数组已经空了也就是$ib >= $lb || 如果c的首元素 < b的首元素,那么取出来c的首元素
    if ($ic < $lc && ($ib >= $lb || $b[$ib] > $c[$ic])) {
        $res[$i++] = $c[$ic++];
    }
}
return $res;

示意图如下:

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!

(0)

相关推荐

  • PHP排序算法之归并排序(Merging Sort)实例详解

    本文实例讲述了PHP排序算法之归并排序(Merging Sort).分享给大家供大家参考,具体如下: 基本思想: 归并排序:就是利用归并(合并)的思想实现的排序方法.它的原理是假设初始序列含有 n 个元素,则可以看成是 n 个有序的子序列,每个子序列的长度为 1,然后两两归并,得到 ⌈ n / 2⌉ (⌈ x ⌉ 表示不小于 x 的最小整数)个长度为 2 或 1 的有序序列:再两两归并,······,如此重复,直至得到一个长度为 n 的有序序列为止,这种排序方法就成为 2 路归并排序. 一.归并

  • PHP常见算法合集代码实例

    许多人都说 算法是程序的核心,一个程序的好于差,关键是这个程序算法的优劣,下面是一些常用的算法和实例,大家可以好好学习下 一.文件夹遍历 <?php function allFile($path = __DIR__, $level = 1) { if (is_dir($path) && is_readable($path)) { if($pd = opendir($path)) { while (($file = readdir($pd)) !== false) { if($file

  • PHP rsa加密解密算法原理解析

    php服务端与客户端交互.提供开放api时,通常需要对敏感的部分api数据传输进行数据加密,这时候rsa非对称加密就能派上用处了,下面通过一个例子来说明如何用php来实现数据的加密解密 1.加密解密的第一步是生成公钥.私钥对,私钥加密的内容能通过公钥解密(反过来亦可以) 下载开源RSA密钥生成工具openssl(通常Linux系统都自带该程序),解压缩至独立的文件夹,进入其中的bin目录,执行以下命令: openssl genrsa -out rsa_private_key.pem 1024 o

  • PHP排序算法系列之归并排序详解

    归并排序 归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用.将已有序的子序列合并,得到完全有序的序列:即先使每个子序列有序,再使子序列段间有序.若将两个有序表合并成一个有序表,称为二路归并. 归并过程 归并排序的核心就是如何将两个有序序列进行合并,假定有两个有序数组,比较两个有序数组的首个元素,谁小就取谁,并将该元素放入第三个数组中,取了之后在相应的数组中将删除此元素,依次类推,当取到一个数组已

  • PHP实现常用排序算法的方法

    本文主要介绍了一些常用的排序算法,以及PHP的代码实现等,希望对您能有所帮助. 本文来自于awaimai.com,由火龙果软件Luca编辑推荐. 作为phper,一般接触算法的编程不多. 但基本的排序算法还是应该掌握. 毕竟算法作为程序的核心,算法的好坏决定了程序的质量. 本文将依次介绍一些常用的排序算法,以及PHP实现. 1 快速排序 快速排序是由东尼·霍尔发展的一种排序算法. 在平均状况下,排序 n 个项目要Ο(n log n)次比较. 在最坏状况下则需要Ο(n2)次比较,但这种状况并不常见

  • PHP哈希表实现算法原理解析

    在PHP内核中,其中一个很重要的数据结构就是HashTable.我们常用的数组,在内核中就是用HashTable来实现.那么,PHP的HashTable是怎么实现的呢?最近在看HashTable的数据结构,但是算法书籍里面没有具体的实现算法,刚好最近也在阅读PHP的源码,于是参考PHP的HashTable的实现,自己实现了一个简易版的HashTable,总结了一些心得,下面给大家分享一下. HashTable的介绍 哈希表是实现字典操作的一种有效数据结构. 定义 简单地说,HashTable(哈

  • php实现归并排序算法的方法详解

    目录 php实现归并排序算法 归并排序原理 总结 php实现归并排序算法 归并排序算法的复杂度是O(nlogn). 代码如下,只需要clone下来执行composer install然后执行 php artisan test:mergeSort 就可以看到结果了 /** * 归并排序把数据逐步分解,然后对分解后的数据进行排序,最后合并到一起 * * @return mixed */ public function handle() { $this->a = [3,70,4,38,5,6,8,4,

  • 使用C++实现全排列算法的方法详解

    复制代码 代码如下: <P>不论是哪种全排列生成算法,都遵循着"原排列"→"原中介数"→"新中介数"→"新排列"的过程.</P><P>其中中介数依据算法的不同会的到递增进位制数和递减进位制数.</P><P>关于排列和中介数的一一对应性的证明我们不做讨论,这里仅仅给出了排列和中介数的详细映射方法.</P> · 递增进位制和递减进位制数  所谓递增进位制和递减

  • Java实现SHA算法的方法详解

    本文实例讲述了Java实现SHA算法的方法.分享给大家供大家参考,具体如下: 一 简介 安全散列算法 固定长度摘要信息 二 SHA算法 SHA-1.SHA-2(SHA-224.SHA-256.SHA384.SHA-512) 三 SHA算法实现 package com.imooc.security.sha; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.s

  • Java实现RSA算法的方法详解

    本文实例讲述了Java实现RSA算法的方法.分享给大家供大家参考,具体如下: 一 介绍 唯一广泛接受并实现 用于数据加密和数字签名 公钥加密.私钥解密 私钥加密.公钥解密 二 RSA参数说明 三 实现 package com.imooc.security.rsa; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.sec

  • TF-IDF算法解析与Python实现方法详解

    TF-IDF(term frequency–inverse document frequency)是一种用于信息检索(information retrieval)与文本挖掘(text mining)的常用加权技术.比较容易理解的一个应用场景是当我们手头有一些文章时,我们希望计算机能够自动地进行关键词提取.而TF-IDF就是可以帮我们完成这项任务的一种统计方法.它能够用于评估一个词语对于一个文集或一个语料库中的其中一份文档的重要程度. 在一份给定的文件里,词频 (term frequency, T

  • PHP排序算法之冒泡排序(Bubble Sort)实现方法详解

    本文实例讲述了PHP排序算法之冒泡排序(Bubble Sort)实现方法.分享给大家供大家参考,具体如下: 基本思想: 冒泡排序是一种交换排序,它的基本思想是:两两比较相邻记录的关键字,如果反序则交换,直到没有反序的记录为止. 最简单排序实现: 我们先来看看在没有学习各种排序方法前经常使用的排序方法(至少我是这样....): //这里使用了类型提示(type hint) array,不熟悉或者不习惯的同学大可去掉,不影响运算结果 function MySort(array &$arr){ $le

  • Go Java算法之比较版本号方法详解

    目录 比较版本号 方法一:字符串切割(Java) 方法二:双指针(Go) 比较版本号 给你两个版本号 version1 和 version2 ,请你比较它们. 版本号由一个或多个修订号组成,各修订号由一个 '.' 连接.每个修订号由 多位数字 组成,可能包含 前导零 .每个版本号至少包含一个字符. 修订号从左到右编号,下标从 0 开始,最左边的修订号下标为 0 ,下一个修订号下标为 1 ,以此类推.例如,2.5.33 和 0.1 都是有效的版本号. 比较版本号时,请按从左到右的顺序依次比较它们的

  • Python_LDA实现方法详解

    LDA(Latent Dirichlet allocation)模型是一种常用而用途广泛地概率主题模型.其实现一般通过Variational inference和Gibbs Samping实现.作者在提出LDA模型时给出了其变分推理的C源码(后续贴出C++改编的类),这里贴出基于Python的第三方模块改写的LDA类及实现. #coding:utf-8 import numpy as np import lda import lda.datasets import jieba import co

  • Java AtomicInteger类的使用方法详解

    首先看两段代码,一段是Integer的,一段是AtomicInteger的,为以下: public class Sample1 { private static Integer count = 0; synchronized public static void increment() { count++; } } 以下是AtomicInteger的: public class Sample2 { private static AtomicInteger count = new AtomicIn

随机推荐