• 算法学习(三):归并排序与逆序对求解


    用php实现一个归并排序算法,并基于归并排序思想求解逆序对数目。

    1. 归并排序:自顶向下

    //自顶向下归并排序:分而治之
    function mergeSortUD(&$a,$s=0,$e=null){//注意此处传引用,否则发生写时赋值
        if(!isset($e)){
            $e = count($a) - 1;
        }
        if(count($a) < 1 || $s >= $e || $s < 0 || $e >= count($a)){
            return;
        }
        $mid = $s + floor(($e - $s) / 2);//注意此处取整数,否则$mid为浮点数
        mergeSortUD($a,$s,$mid);
        mergeSortUD($a,$mid+1,$e);
        merge($a,$s,$mid,$e);
    }
    function merge(&$a,$s,$mid,$e){
        $m = [];
        $ms = 0;
        $i = $s;
        $j = $mid+1;
        while($i <= $mid && $j <= $e){
            if($a[$i] < $a[$j]){
                $m[$ms++] = $a[$i++];
            }elseif($a[$i] == $a[$j]){
                $m[$ms++] = $a[$i++];
                $m[$ms++] = $a[$j++];
            }else{
                $m[$ms++] = $a[$j++];
            }
        }
        while($i <= $mid){
            $m[$ms++] = $a[$i++];
        }
        while($j <= $e){
            $m[$ms++] = $a[$j++];
        }
        //将排好序的子区间复制到原数组
        foreach($m as $k => $v){
            $a[$s++] = $v;
        }
    }
    $a = [9,8,7,6,5,4,3,2,1,0];
    mergeSortUD($a);
    var_dump($a);

    2.归并排序:自底向上

    //自底向上归并排序:从局部到整体
    function mergeSortDU(&$a,$s=0,$e=null){
        if(!isset($e)){
            $e = count($a) - 1;
        }
        if(count($a) < 1 || $s >= $e || $s < 0 || $e >= count($a)){
            return;
        }
        
        $size = 1;
        $maxSize = count($a);
        while($size <= $maxSize){
            $i = $s;
            while($i <= $e){
                merge($a,$i,min($i+$size-1,$e),min($i+2*$size-1,$e));
                $i = $i+2*$size;
            }
            $size = $size * 2;
        }
    }
    $a = [9,8,7,6,5,4,3,2,1,0];
    mergeSortDU($a);
    var_dump($a);

    3. 求解逆序对数

    借用自顶向下归并排序的思想,每次merge逐个比较子区间元素大小时,若左子区间的元素大于右子区间元素值,则逆序对数累加。

    function rmergeSort($a,$s,$e){
        if(count($a) < 1 || $s >= $e || $s < 0 || $e >= count($a)){
            return;
        }
        $mid = $s + floor(($e - $s) / 2);//注意此处取整数,否则$mid为浮点数
        rmergeSort($a,$s,$mid);
        rmergeSort($a,$mid+1,$e);
        rmerge($a,$s,$mid,$e);
    }
    function rmerge(&$a,$s,$mid,$e){
        global $reverseCount;
        $m = [];
        $ms = 0;
        $i = $s;
        $j = $mid+1;
        while($i <= $mid && $j <= $e){
            if($a[$i] < $a[$j]){
                $m[$ms++] = $a[$i++];
            }elseif($a[$i] == $a[$j]){
                $m[$ms++] = $a[$i++];
                $m[$ms++] = $a[$j++];
            }else{
                $reverseCount++;//找到逆序对
                $m[$ms++] = $a[$j++];
            }
        }
        while($i <= $mid){
            $m[$ms++] = $a[$i++];
        }
        while($j <= $e){
            $m[$ms++] = $a[$j++];
        }
        //将排好序的子区间复制到原数组
        foreach($m as $k => $v){
            $a[$s++] = $v;
        }
    }
    $reverseCount = 0; $a = [9,8,7,6,5,4,3,2,1,0]; rmergeSort($a,0,9); var_dump($a); echo '逆序对数目:'.$reverseCount;
  • 相关阅读:
    HTK(V3.1)基础指南中文版(转载)
    声纹识别公司Neurotechnology
    微软亚洲研究院语音组的研究成果
    Matlab P文件——加快Matlab程序,保护你的算法
    Intel嵌入式事业部的4条线
    语音增强国外牛人
    NHibernate Linq 的 join (联合查询) 的例子
    NHibernate HQL 函数例子
    使用TQ作在线客服系统
    ADI的SHARC系列处理器的内核PLL管理(4.2)
  • 原文地址:https://www.cnblogs.com/ling-diary/p/9401775.html
Copyright © 2020-2023  润新知