zoukankan      html  css  js  c++  java
  • 算法学习(三):归并排序与逆序对求解

    用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;
  • 相关阅读:
    关于键保留表的一些汇总
    pl/sql,Oracle数据库中,不小心delete数据并提交后如何恢复被删数据
    创建视图的with check option选项。
    oracle中update,insert,delete的高级用法
    物化视图详解--介绍、创建方法、例子
    Oracle 视图备忘
    利用替换变量提高Oracle交互性(define)
    Sqlplus中的VARIABLE以及使用VARIABLE之后使用execute。
    Unity3d 引擎原理详细介绍
    Unity 3D主要特性和缺陷
  • 原文地址:https://www.cnblogs.com/ling-diary/p/9401775.html
Copyright © 2011-2022 走看看