PHP实现各种经典算法详解

<?  
//--------------------  
// 基本数据结构算法 
//--------------------  
//二分查找(数组里查找某个元素)  
function bin_sch($array,  $low, $high, $k){   
    if ( $low <= $high){   
        $mid =  intval(($low+$high)/2 );   
        if ($array[$mid] ==  $k){   
            return $mid;   
        }elseif ( $k < $array[$mid]){   
            return  bin_sch($array, $low,  $mid-1, $k);   
        }else{   
            return  bin_sch($array, $mid+ 1, $high, $k);   
        }   
    }   
    return -1;   
}   
//顺序查找(数组里查找某个元素)  
function  seq_sch($array, $n,  $k){   
    $array[$n] =  $k;   
    for($i=0;  $i<$n; $i++){   
        if( $array[$i]==$k){   
            break;   
        }   
    }   
    if ($i<$n){   
        return  $i;   
    }else{   
        return -1;   
    }   
}   
//线性表的删除(数组中实现)  
function delete_array_element($array , $i)  
{  
        $len =  count($array);   
        for ($j= $i; $j<$len; $j ++){  
                $array[$j] = $array [$j+1];  
        }  
        array_pop ($array);  
        return $array ;  
}  
//冒泡排序(数组排序)  
function bubble_sort( $array)  
{  
        $count = count( $array);  
        if ($count <= 0 ) return false;  
        for($i=0 ; $i<$count; $i ++){  
                for($j=$count-1 ; $j>$i; $j--){  
                        if ($array[$j] < $array [$j-1]){  
                                 $tmp = $array[$j];  
                                 $array[$j] = $array[ $j-1];  
                                $array [$j-1] = $tmp;  
                        }  
                }  
        }  
        return $array;  
}  
//快速排序(数组排序)  
//选取一个标准,和其他数据对比后将数据分为两批,递归执行后合并
function quick_sort($array ) {  
        if (count($array) <= 1) return  $array;  
        $key = $array [0];  
        $left_arr  = array();  
        $right_arr = array();  
        for ($i= 1; $i<count($array ); $i++){  
                if ($array[ $i] <= $key)  
                        $left_arr [] = $array[$i];  
                else  
                         $right_arr[] = $array[$i ];  
        }  
        $left_arr = quick_sort($left_arr );  
        $right_arr = quick_sort( $right_arr);  
        return array_merge($left_arr , array($key), $right_arr);  
}  
 
//------------------------  
// PHP内置字符串函数实现  
//------------------------  
//字符串长度  
function strlen ($str)  
{  
        if ($str == '' ) return 0;  
        $count =  0;  
        while (1){  
                if ( $str[$count] != NULL){  
                         $count++;  
                        continue;  
                }else{  
                        break;  
                }  
        }  
        return $count;  
}  
//截取子串  
function substr($str, $start,  $length=NULL)  
{  
        if ($str== '' || $start>strlen($str )) return;  
        if (($length!=NULL) && ( $start>0) && ($length> strlen($str)-$start)) return;  
        if (( $length!=NULL) && ($start< 0) && ($length>strlen($str )+$start)) return;  
        if ($length ==  NULL) $length = (strlen($str ) - $start);  
          
        if ($start <  0){  
                for ($i=(strlen( $str)+$start); $i<(strlen ($str)+$start+$length ); $i++) {  
                        $substr .=  $str[$i];  
                }  
        }  
        if ($length  > 0){  
                for ($i= $start; $i<($start+$length ); $i++) {  
                        $substr  .= $str[$i];  
                }  
        }  
        if ( $length < 0){  
                for ($i =$start; $i<(strlen( $str)+$length); $i++) {  
                        $substr .= $str[$i ];  
                }  
        }  
        return $substr;  
}  
//字符串翻转  
function strrev($str)  
{  
        if ($str == '') return 0 ;  
        for ($i=(strlen($str)- 1); $i>=0; $i --){  
                $rev_str .= $str[$i ];  
        }  
        return $rev_str;  
}  
 
//字符串比较  
function strcmp($s1,  $s2)  
{  
        if (strlen($s1) <  strlen($s2)) return -1 ;  
        if (strlen($s1) > strlen( $s2)) return 1;  
        for ($i =0; $i<strlen($s1 ); $i++){  
                if ($s1[ $i] == $s2[$i]){  
                        continue;  
                }else{  
                        return false;  
                }  
        }  
        return  0;  
}  
 
//查找字符串  
function  strstr($str, $substr)  
{  
         $m = strlen($str);  
        $n = strlen($substr );  
        if ($m < $n) return false ;  
        for ($i=0; $i <=($m-$n+1); $i ++){  
                $sub = substr( $str, $i, $n);  
                if ( strcmp($sub, $substr) ==  0)  return $i;  
        }  
        return false ;  
}  
//字符串替换  
function str_replace($substr , $newsubstr, $str)  
{  
         $m = strlen($str);  
        $n = strlen($substr );  
        $x = strlen($newsubstr );  
        if (strchr($str, $substr ) == false) return false;  
        for ( $i=0; $i<=($m- $n+1); $i++){  
                 $i = strchr($str,  $substr);  
                $str = str_delete ($str, $i, $n);  
                $str = str_insert($str,  $i, $newstr);  
        }  
        return $str ;  
}  
 
//--------------------  
// 自实现字符串处理函数 
//--------------------  
//插入一段字符串  
function str_insert($str, $i , $substr)  
{  
        for($j=0 ; $j<$i; $j ++){  
                $startstr .= $str[$j ];  
        }  
        for ($j=$i; $j <strlen($str); $j ++){  
                $laststr .= $str[$j ];  
        }  
        $str = ($startstr . $substr  . $laststr);  
        return $str ;  
}  
//删除一段字符串  
function str_delete($str , $i, $j)  
{  
        for ( $c=0; $c<$i;  $c++){  
                $startstr .= $str [$c];  
        }  
        for ($c=( $i+$j); $c<strlen ($str); $c++){  
                $laststr  .= $str[$c];  
        }  
         $str = ($startstr . $laststr );  
        return $str;  
}  
//复制字符串  
function strcpy($s1, $s2 )  
{  
        if (strlen($s1)==NULL || !isset( $s2)) return;  
        for ($i=0 ; $i<strlen($s1);  $i++){  
                $s2[] = $s1 [$i];  
        }  
        return $s2;  
}  
//连接字符串  
function strcat($s1 , $s2)  
{  
        if (!isset($s1) || !isset( $s2)) return;  
        $newstr = $s1 ;  
        for($i=0; $i <count($s); $i ++){  
                $newstr .= $st[$i ];  
        }  
        return $newsstr;  
}  
//简单编码函数(与php_decode函数对应)  
function php_encode($str)  
{  
        if ( $str=='' && strlen( $str)>128) return false;  
        for( $i=0; $i<strlen ($str); $i++){  
                 $c = ord($str[$i ]);  
                if ($c>31 && $c <107) $c += 20 ;  
                if ($c>106 && $c <127) $c -= 75 ;  
                $word = chr($c );  
                $s .= $word;  
        }   
        return $s;   
}  
//简单解码函数(与php_encode函数对应)  
function php_decode($str)  
{  
        if ( $str=='' && strlen($str )>128) return false;  
        for( $i=0; $i<strlen ($str); $i++){  
                $c  = ord($word);  
                if ( $c>106 && $c<127 ) $c = $c-20;  
                if ($c>31 && $c< 107) $c = $c+75 ;  
                $word = chr( $c);  
                $s .= $word ;  
        }   
        return $s;   
}  
//简单加密函数(与php_decrypt函数对应)  
function php_encrypt($str)  
{  
         $encrypt_key = 'abcdefghijklmnopqrstuvwxyz1234567890';  
         $decrypt_key = 'ngzqtcobmuhelkpdawxfyivrsj2468021359';  
        if ( strlen($str) == 0) return  false;  
        for ($i=0;  $i<strlen($str); $i ++){  
                for ($j=0; $j <strlen($encrypt_key); $j ++){  
                        if ($str[$i] == $encrypt_key [$j]){  
                                $enstr .=  $decrypt_key[$j];  
                                break;  
                        }  
                }  
        }  
        return $enstr;  
}  
//简单解密函数(与php_encrypt函数对应)  
function php_decrypt($str)  
{  
         $encrypt_key = 'abcdefghijklmnopqrstuvwxyz1234567890';  
         $decrypt_key = 'ngzqtcobmuhelkpdawxfyivrsj2468021359';  
        if ( strlen($str) == 0) return  false;  
        for ($i=0;  $i<strlen($str); $i ++){  
                for ($j=0; $j <strlen($decrypt_key); $j ++){  
                        if ($str[$i] == $decrypt_key [$j]){  
                                $enstr .=  $encrypt_key[$j];  
                                break;  
                        }  
                }  
        }  
        return $enstr;  
}  
?> 

 

原文链接:https://blog.csdn.net/aaroun/article/details/79132305

 

PHP版常用算法

//冒泡
//逐行对比,满足条件则交换
function bubbleSort($arrData,$sort = 'desc')
{
    if(empty($arrData)) return $arrData;

    //默认有序
    $isSorted = true;
    $nCount = count($arrData);
    for($i = 0; $i < $nCount; $i++) {

        //对比次数随着循环逐渐减少,因为后面的数据已经处理为有序
        for($j = 0; $j < ($nCount - $i - 1); $j++) {
            //执行判断
            $isChange = $sort == 'desc' ? $arrData[$j] < $arrData[$j+1] : $arrData[$j] > $arrData[$j+1];

            if($isChange) {
                //首次对比,判断是否有序
                $isSorted = false;

                $temp = $arrData[$j];
                $arrData[$j] = $arrData[$j+1];
                $arrData[$j+1] = $temp;
            }
        }

        if($isSorted) break;
    }

    return $arrData;
}
--------------------- 

//快速排序
//选取一个标准,和其他数据对比后将数据分为两批,递归执行后合并
function quickSort(&$arr, $sort = 'asc'){

    //检查数据,多于一个数据才执行
    $nCount = count($arr);
    if($nCount > 1) {
        //选取标准(第一个数据)
        $nStandard = $arr[0];
        $arrLeftData = [];
        $arrRightData = [];
        //遍历,注意这里从1开始比较
        for($i = 1; $i < $nCount; $i++) {

            if($sort == 'desc') {
                $arr[$i] > $nStandard ? $arrLeftData[] = $arr[$i] : $arrRightData[] = $arr[$i];
            } else {
                $arr[$i] > $nStandard ? $arrRightData[] = $arr[$i] : $arrLeftData[] = $arr[$i];
            }
        }
        $arr = array_merge($this->quickSort($arrLeftData, $sort), array($nStandard), $this->quickSort($arrRightData, $sort));
    }
    return $arr;
}
--------------------- 

归并排序
//利用归并(合并)的思想实现的排序方法。
//它的原理是假设初始序列含有 n 个元素,则可以看成是 n 个有序的子序列,每个子序列的长度为 1,然后两两归并
//得到n/2个长度为2或1 的有序序列;再两两归并,······,如此重复
//直至得到一个长度为 n 的有序序列为止,这种排序方法就成为 2 路归并排序

//merge函数将指定的两个有序数组(arr1,arr2)合并并且排序
//我们可以找到第三个数组,然后依次从两个数组的开始取数据哪个数据小就先取哪个的,然后删除掉刚刚取过的数据
function al_merge($arrA,$arrB)
{
    $arrC = array();
    while(count($arrA) && count($arrB)){
        //这里不断的判断哪个值小,就将小的值给到arrC,但是到最后肯定要剩下几个值,
        //不是剩下arrA里面的就是剩下arrB里面的而且这几个有序的值,肯定比arrC里面所有的值都大
        $arrC[] = $arrA[0] < $arrB[0] ? array_shift($arrA) : array_shift($arrB);
    }
    return array_merge($arrC, $arrA, $arrB);
}

//归并排序函数
function al_merge_sort($arr){
    $len = count($arr);
    if($len <= 1) return $arr;//递归结束条件,到达这步的时候,数组就只剩下一个元素了,也就是分离了数组

    //分离数组元素
    $mid = intval($len/2);//取数组中间
    $left_arr = array_slice($arr, 0, $mid);//拆分数组0-mid这部分给左边left_arr
    $right_arr = array_slice($arr, $mid);//拆分数组mid-末尾这部分给右边right_arr
    $left_arr = $this->al_merge_sort($left_arr);//左边拆分完后开始递归合并往上走
    $right_arr = $this->al_merge_sort($right_arr);//右边拆分完毕开始递归往上走

    $arr = $this->al_merge($left_arr, $right_arr);//合并两个数组,继续递归
    return $arr;
}
--------------------- 

二分查找
//二分查找
//假设数据是按升序排序的,对于给定值x,从序列的中间位置开始比较,如果当前位置值等于x,则查找成功;
//若x小于当前位置值,则在数列的前半段中查找;若x大于当前位置值则在数列的后半段中继续查找,直到找到为止
function binSearch($toSearch,$arr)
{
    //确定当前的检索范围
    $nCount = count($arr);
    //低位键,初始为0
    $nLowNum = 0;
    //高位键,初始为末尾 
    $nHighNum = $nCount - 1;

    while($nLowNum <= $nHighNum) {
        //选定大概中间键
        $nMiddleNum = intval(($nHighNum + $nLowNum)/2);

        if($arr[$nMiddleNum] > $toSearch) {
            //比检索值大
            $nHighNum = $nMiddleNum - 1;
        } elseif ($arr[$nMiddleNum] < $toSearch) {
            //比检索值小
            $nLowNum = $nMiddleNum + 1;
        } else {
            return $nMiddleNum;
        }
    }

    return false;
}
--------------------- 

//顺序查找
function seqSearch($arr,$toSearch)
{
    $nCount = count($arr);

    for ($i=0; $i < $nCount; $i++) {
        if ($arr[$i] == $toSearch) {
            return $i;
        }
    }
    return -1;
}
--------------------- 

选择排序
//在第一次循环中,假设第一个数是最小的;然后跟第二个数比较,一直比到最后,找出最小值,然后把最小值跟第一个数的位置互换;
//再进行下一次循环,找出最小值跟第二个位置的数互换;一直循环数组的个数减去1次;数组就成了有序的了 
function selectSort($arr)
{

    $nCount = count($arr);
    //遍历取得需要排序的数
    for($i = 0; $i < $nCount; $i++) {

        //选择需要比较的数,从$i开始到结束
        for($j = $i + 1; $j < $nCount; $j++) {
            //比较
            if($arr[$j] < $arr[$i]) {
                $temp = $arr[$i];
                $arr[$i] = $arr[$j];
                $arr[$j] = $temp;
            }
        }
    }
    return $arr;  
}
--------------------- 

外部排序+多路归并
思路参考: https://blog.csdn.net/itermeng/article/details/77824866

面试中经常问到一些关于 并行计算 或者 在一台内存不多的机器上进行大文件排序 的问题,这些其实思路都可以借助外部排序+多路归并去解决:

1.只能一部分放在放在内存数组中,另一部分放在内存之外(硬盘或网络其它节点),这就是所谓的外部排序;
2.归并排序:将数据分为左右两部分,分别排序,再把两个有序子数组进行归并;
3.重点就是归并过程,就是两个已排序好的数组来比较头部的元素,取最小值放入最终数组中;

思路:

第一步:将数据进行切分,例如以100m将1G的文件分为10组,将每一段数据分配到外部,切分的大小符合节点内存大小限制;
第二步:这样每个节点各自对分配数据进行排序,采用归并排序或快速排序皆可(多节点则节点处理,单机则逐个处理);
第三步:将每个排序好的节点按照归并算法整合到一个节点(多路归并);
--------------------- 
作者:某文宇 
来源:CSDN 
原文:https://blog.csdn.net/suilz/article/details/80013241 
版权声明:本文为博主原创文章,转载请附上博文链接!

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
├──Package │ ├── Sort 排序篇 │ │ ├── BubbleSort.php 冒泡排序 │ │ ├── HeapSort.php 堆排序 大根堆 │ │ ├── MBaseSort.php 基数排序 MSD │ │ ├── LBaseSort.php 基数排序 LSD │ │ ├── QuickSort.php 快速排序 │ │ ├── ShuttleSort.php 飞梭排序 │ │ ├── ShellSort.php 希尔排序 │ │ ├── MergeSort.php 归并排序 │ │ ├── InsertSort.php 插入排序 │ │ └── SelectSort.php 选择排序 │ │ │ ├── Query 查找篇 │ │ ├── BinaryQuery.php 二分查找 │ │ ├── InseertQuery.php 插入查找 │ │ ├── FibonacciQuery.php 斐波那契查找 │ │ ├── BFSQuery.php 广度优先查找 │ ├── Kmp.php 算法导论-KMP算法 │ ├── DijkstraQuery.php 迪克斯特拉算法 │ │ └── QulickQuery.php 快速查找 │ │ │ ├── Structure 数据结构 │ │ ├── StackExample.php 堆栈 先进后出 LIFO (Last In First Out) │ │ ├── LinearChain.php 线性表 单链存储 │ │ └── LinearOrder.php 线性表 顺序存储 │ │ └── BinarySearchTree.php 二叉搜索树 │ │ │ ├── Tools 小工具集 │ │ └── SystemSwitch.php 堆栈实现进制转换 │ │ │ └── Other 其他 │ ├── MonkeyKing.php 约瑟夫环 │ ├── DynamicProgramming.php 动态规划 │ ├── Fibonacci.php 斐波那契数列 │ ├── StealingApples.php 偷苹果求余 │ ├── HanoiGames.php 汉诺塔游戏 │ ├── BidirectionalQueue.php 双向队列 │ ├── ColorBricks.php 彩色砖块 │ ├── GetCattle.php 牛年求牛 │ ├── OnlyNumbers.php 求唯一数 │ ├── PokerGames.php 洗扑克牌 │ ├── Interval.php 抽奖区间算法 │ ├── Maze.php 迷宫寻址算法 │ ├── AntsClimb.php 蚂蚁爬杆算法 │ ├── Encryption.php 对称加密算法 │ ├── ElevatorDispatch.php 编程之美-电梯调度算法 │ ├── PointInTriangle.php 向量叉集计算点是否在三角形中 │ ├── TraversalOfBinary.php 二叉树非递归遍历算法实现 │ ├── Knapsack.php 贪心算法之背包问题实现 │ └── BigSmallReplace.php Hello World 输出 Olleh Dlrow │ └── Solution.php Facebook面试题之岛屿周长算法 │ └── RotationSort.php Facebook面试题之顺时针回旋算法 │ └── Square.php Facebook面试题之判断四个点能否组成正方形算法 │ └── Prim.php Prim算法(最小生成树算法) │ └── CartesianProduct.php 笛卡尔积算法 │ └── Square.php 面试题之平面任意四点能否组成一个矩形 │ └── Judge.php 面试题之扑克牌中任选五张判断是不是顺子 │ └── Factorial.php 面试题之N的阶乘末尾有多少个0

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值