排序算法分析汇总(PHP版本)【更新中】

/***
     * @param $arr
     * @return mixed
     * 冒泡排序【重复比较两个相邻的元素,如果位置错误则对调位置,直至没有元素需要对换】
     * 分类 -------------- 内部比较排序
     * 数据结构 ---------- 数组
     * 最差时间复杂度 ---- O(n^2)
     * 最优时间复杂度 ---- 如果能在内部循环第一次运行时,使用一个旗标来表示有无需要交换的可能,可以把最优时间复杂度降低到O(n)
     * 平均时间复杂度 ---- O(n^2)
     * 所需辅助空间 ------ O(1)
     * 稳定性 ------------ 稳定
     */
    private function bubbleSort($arr){
        for ($i=0;$i<count($arr);$i++){
            for ($j=0;$j<count($arr)-1;$j++){
                if($arr[$j] > $arr[$j+1]){
                    $tmp = $arr[$j];
                    $arr[$j]=$arr[$j+1];
                    $arr[$j+1] = $tmp;
                }
            }
        }
        return $arr;
    }

    /**
     * @param $arr
     * @return mixed
     * 鸡尾酒排序【又叫定向冒泡排序,冒泡排序的一种改进,先向右排序出最大的那个,然后向左排序出最小的,周而复此】
     * 分类 -------------- 内部比较排序
     * 数据结构 ---------- 数组
     * 最差时间复杂度 ---- O(n^2)
     * 最优时间复杂度 ---- 如果序列在一开始已经大部分排序过的话,会接近O(n)
     * 平均时间复杂度 ---- O(n^2)
     * 所需辅助空间 ------ O(1)
     * 稳定性 ------------ 稳定
     */
    private function cocktailSort($arr){

        $left = 0;
        $right = count($arr)-1;
        while ($left < $right){
            for ($i=$left;$i<$right;$i++){
                if($arr[$i] > $arr[$i+1]){
                    $tmp = $arr[$i];
                    $arr[$i]=$arr[$i+1];
                    $arr[$i+1] = $tmp;
                }
            }
            $left++;
            for ($i=$right;$i>$left;$i--){
                if($arr[$i-1] > $arr[$i]){
                    $tmp = $arr[$i-1];
                    $arr[$i-1]=$arr[$i];
                    $arr[$i] = $tmp;
                }
            }
            $right--;
        }
        return $arr;
    }

    /**
     * @param $arr
     * @return mixed
     * 选择排序【找出第1/2/3/4/../n个最小(大)的值放到相应的位置,然后继续找出下一个未排序的最小(大)值】
     * 分类 -------------- 内部比较排序
     * 数据结构 ---------- 数组
     * 最差时间复杂度 ---- O(n^2)
     * 最优时间复杂度 ---- O(n^2)
     * 平均时间复杂度 ---- O(n^2)
     * 所需辅助空间 ------ O(1)
     * 稳定性 ------------ 不稳定
     */
    private function chooseSort($arr){
        for ($i=0;$i<count($arr);$i++){
            $min = $i;
            //因为是从i开始比较,所以i+1
            for ($j=$i+1;$j<count($arr);$j++){
                if($arr[$min]>$arr[$j]){
                    $min = $j;
                }
            }
            if($min != $i){
                $tmp = $arr[$i];
                $arr[$i] = $arr[$min];
                $arr[$min] = $tmp;
            }
        }
        return $arr;
    }

    /**
     * @param $arr
     * @return mixed
     * 插入排序【往左一个个比较】
     * 分类 ------------- 内部比较排序
     * 数据结构 ---------- 数组
     * 最差时间复杂度 ---- 最坏情况为输入序列是降序排列的,此时时间复杂度O(n^2)
     * 最优时间复杂度 ---- 最好情况为输入序列是升序排列的,此时时间复杂度O(n)
     * 平均时间复杂度 ---- O(n^2)
     * 所需辅助空间 ------ O(1)
     * 稳定性 ------------ 稳定
     */
    private function insertSort($arr){
        for ($i=1;$i<count($arr);$i++){
            $get = $arr[$i];
            $j = $i-1;
            while($j>=0 && $arr[$j]>$get){
                $arr[$j+1] = $arr[$j];
                $j--;
            }
            $arr[$j+1] = $get;
        }
        return $arr;
    }

    
/**
     * 希尔排序(递减增量排序,插入排序的一种更搞笑改进版本)
     * 分类 -------------- 内部比较排序
     * 数据结构 ---------- 数组
     * 最差时间复杂度 ---- 根据步长序列的不同而不同。已知最好的为O(n(logn)^2)
     * 最优时间复杂度 ---- O(n)
     * 平均时间复杂度 ---- 根据步长序列的不同而不同。
     * 所需辅助空间 ------ O(1)
     * 稳定性 ------------ 不稳定
     */
    private function shellSort($arr){
        $h = 0;
        $count = count($arr);
        while($h<$count){
            $h=3*$h+1;
        }

        while ($h>=1){
            for ($i=$h;$i<$count;$i++){
                $j=$i-$h;
                $get = $arr[$i];
                while ($j>=0 && $arr[$j] > $get){
                    $arr[$j+$h] = $arr[$j];
                    $j = $j-$h;
                }
                $arr[$j+$h] = $get;
            }
            $h = ($h-1)/3;
        }
        return $arr;
    }

    /**
     * 归并排序
     * 分开 -------------- 内部比较排序
     * 数据结构 ----------- 数组
     * 最差时间复杂度 ------ O
     * 最有时间复杂度 ------ O
     * 平均时间复杂度 ------ O
     * 所需辅助空间 -------- O(n)
     * 稳定性 ------------- 稳定
     */
    private function mergeSort($arr){
        $len = count($arr);
        if($len <= 1)   return $arr;
        $mid = intval($len/2);
        $leftArr = array_slice($arr,0,$mid);
        $rightArr = array_slice($arr,$mid);
        $leftArr = $this->mergeSort($leftArr);
        $rightArr = $this->mergeSort($rightArr);
        $arr = $this->mergeArr($leftArr,$rightArr);
        return $arr;
    }

    private function mergeArr($arr1,$arr2){
        $arr3 = array();
        while (count($arr1) && count($arr2)){
            $arr3[] = $arr1['0']<$arr2['0']?array_shift($arr1):array_shift($arr2);
        }
        return array_merge($arr3,$arr1,$arr2);
    }

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这里是用PHP写的几个基础算法算法的重要性貌似对于PHP程序员不怎么重要,其实是非常重要的,经典名句:算法+数据结构=程序。作为一名真正的高级PHP程序员,我认为应该熟悉C,如果你想成为真正的程序员,请好好学C,学好数据结构算法。这里仅仅只是几个基础算法,还有很多东东要学…… 1、首先来画个菱形玩玩,很多人学C时在书上都画过,咱们用PHP画下,画了一半。 思路:多少行for一次,然后在里面空格和星号for一次。 <?phpfor($i=0;$i<=3;$i++){ for($j=0;$j<=3-$i;$j++){ echo ' '; } for($k=0;$k<=2*$i;$k++){ echo '*'; } echo '<br/>'; } 2、冒泡排序,C里基础算法,从小到大对一组数排序。 思路:这题从小到大,第一轮排最小,第二轮排第二小,第三轮排第三小,依次类推…… <?php$arr = array(3, 2, 1);$n = count($arr); //每循环一次,就跑一趟后面的排序for($j=0; $j<$n-1; $j++) {//对后面没排好的,循环查找出最大(最小)的,进行一趟排序 for($i=$j; $i<$n-1; $i++) { if($arr[$j] > $arr[$i+1]) { $t = $arr[$j]; $arr[$j] = $arr[$i+1]; $arr[$i+1] = $t; } }}print_r($arr); 3、杨辉三角,用PHP写。 思路:每一行的第一位和最后一位是1,没有变化,间是前排一位与左边一排的和,这种算法是用一个二维数组保存,另外有种算法用一维数组也可以实现,一行一行的输出,有兴趣去写着玩下。 11 11 2 11 3 3 11 4 6 4 11 5 10 10 5 1 <?php//每行的第一个和最后一个都为1,写了6行 for($i=0; $i<6; $i++) { $a[$i][0]=1; $a[$i][$i]=1; } //出除了第一位和最后一位的值,保存在数组 for($i=2; $i<6; $i++) { for($j=1; $j<$i; $j++) { $a[$i][$j] = $a[$i-1][$j-1]+$a[$i-1][$j]; } } //打印 for($i=0; $i<6; $i++){ for($j=0; $j<=$i; $j++) { echo $a[$i][$j].' '; } echo '<br/>'; } 4、在一组数,要求插入一个数,按其原来顺序插入,维护原来排序方式。 思路:找到比要插入数大的那个位置,替换,然后把后面的数后移一位。 <?php$in = 2;$arr = array(1,1,1,3,5,7);$n = count($arr);//如果要插入的数已经最大,直接打印if($arr[$n-1] < $in) { $arr[$n+1] = $in; print_r($arr); } for($i=0; $i<$n; $i++) {//找出要插入的位置 if($arr[$i] >= $in){ $t1= $arr[$i]; $arr[$i] = $in;//把后面的数据后移一位 for($j=$i+1; $j<$n+1; $j++) { $t2 = $arr[$j]; $arr[$j] = $t1; $t1 = $t2; }//打印 print_r($arr); die; }} 5、对一组数进行排序(快速排序算法)。 思路:通过一趟排序分成两部分,然后递归对这两部分排序,最后合并。 <?phpfunction q($array) { if (count($array) <= 1) {return $array;}//以$key为界,分成两个子数组 $key = $array[0]; $l = array(); $r = array(); //分别进行递归排序,然后合成一个数组 for ($i=1; $i<count($array); $i++) { if ($array[$i] <= $key) { $l[] = $array[$i]; } else { $r[] = $array[$i]; } } $l = q($l); $r = q($r); return array_merge($l, array($key), $r);} $arr = array(1,2,44,3,4,33);print_r( q($arr) ); 6、在一个数组查找你所需元素(二分查找算法)。 思路:以数组某个值为界,再递归进行查找,直到结束。 <?phpfunction find($array, $low, $high, $k){ if ($low <= $high){ $mid = intval(($low+$high)/2); if ($array[$mid] == $k){ return $mid; }elseif ($k < $array[$mid]){ return find($array, $low, $mid-1, $k); }else{ return find($array, $mid+1, $high, $k); } } die('Not have...');} //test$array = array(2,4,3,5);$n = count($array);$r = find($array,0,$n, 7、合并多个数组,不用array_merge(),题目来于论坛。 思路:遍历每个数组,重新组成一个新数组。 <?phpfunction t(){ $c = func_num_args()-1; $a = func_get_args(); //print_r($a); for($i=0; $i<=$c; $i++){ if(is_array($a[$i])){ for($j=0; $j<count($a[$i]); $j++){ $r[] = $a[$i][$j]; } } else { die('Not a array!'); } } return $r;} //testprint_r(t(range(1,4),range(1,4),range(1,4)));echo '<br/>';$a = array_merge(range(1,4),range(1,4),range(1,4));print_r($a); 8、牛年求牛:有一母牛,到4岁可生育,每年一头,所生均是一样的母牛,到15岁绝育,不再能生,20岁死亡,问n年后有多少头牛。(来自论坛) <?phpfunction t($n) { static $num = 1 for($j=1; $j<=$n; $j++){ if($j>=4 && $j<15) {$num++;t($n-$j);} if($j==20){$num--;} } return $num;} //testecho t(8); 这里是用PHP写的几个基础算法算法的重要性貌似对于PHP程序员不怎么重要,其实是非常重要的,经典名句:算法+数据结构=程序。作为一名真正的高级PHP程序员,我认为应该熟悉C,如果你想成为真正的程序员,请好好学C,学好数据结构算法。这里仅仅只是几个基础算法,还有很多东东要学…… 1、首先来画个菱形玩玩,很多人学C时在书上都画过,咱们用PHP画下,画了一半。 思路:多少行for一次,然后在里面空格和星号for一次。 <?phpfor($i=0;$i<=3;$i++){ for($j=0;$j<=3-$i;$j++){ echo ' '; } for($k=0;$k<=2*$i;$k++){ echo '*'; } echo '<br/>'; } 2、冒泡排序,C里基础算法,从小到大对一组数排序。 思路:这题从小到大,第一轮排最小,第二轮排第二小,第三轮排第三小,依次类推…… <?php$arr = array(3, 2, 1);$n = count($arr); //每循环一次,就跑一趟后面的排序for($j=0; $j<$n-1; $j++) {//对后面没排好的,循环查找出最大(最小)的,进行一趟排序 for($i=$j; $i<$n-1; $i++) { if($arr[$j] > $arr[$i+1]) { $t = $arr[$j]; $arr[$j] = $arr[$i+1]; $arr[$i+1] = $t; } }}print_r($arr); 3、杨辉三角,用PHP写。 思路:每一行的第一位和最后一位是1,没有变化,间是前排一位与左边一排的和,这种算法是用一个二维数组保存,另外有种算法用一维数组也可以实现,一行一行的输出,有兴趣去写着玩下。 11 11 2 11 3 3 11 4 6 4 11 5 10 10 5 1 <?php//每行的第一个和最后一个都为1,写了6行 for($i=0; $i<6; $i++) { $a[$i][0]=1; $a[$i][$i]=1; } //出除了第一位和最后一位的值,保存在数组 for($i=2; $i<6; $i++) { for($j=1; $j<$i; $j++) { $a[$i][$j] = $a[$i-1][$j-1]+$a[$i-1][$j]; } } //打印 for($i=0; $i<6; $i++){ for($j=0; $j<=$i; $j++) { echo $a[$i][$j].' '; } echo '<br/>'; } 4、在一组数,要求插入一个数,按其原来顺序插入,维护原来排序方式。 思路:找到比要插入数大的那个位置,替换,然后把后面的数后移一位。 <?php$in = 2;$arr = array(1,1,1,3,5,7);$n = count($arr);//如果要插入的数已经最大,直接打印if($arr[$n-1] < $in) { $arr[$n+1] = $in; print_r($arr); } for($i=0; $i<$n; $i++) {//找出要插入的位置 if($arr[$i] >= $in){ $t1= $arr[$i]; $arr[$i] = $in;//把后面的数据后移一位 for($j=$i+1; $j<$n+1; $j++) { $t2 = $arr[$j]; $arr[$j] = $t1; $t1 = $t2; }//打印 print_r($arr); die; }} 5、对一组数进行排序(快速排序算法)。 思路:通过一趟排序分成两部分,然后递归对这两部分排序,最后合并。 <?phpfunction q($array) { if (count($array) <= 1) {return $array;}//以$key为界,分成两个子数组 $key = $array[0]; $l = array(); $r = array(); //分别进行递归排序,然后合成一个数组 for ($i=1; $i<count($array); $i++) { if ($array[$i] <= $key) { $l[] = $array[$i]; } else { $r[] = $array[$i]; } } $l = q($l); $r = q($r); return array_merge($l, array($key), $r);} $arr = array(1,2,44,3,4,33);print_r( q($arr) ); 6、在一个数组查找你所需元素(二分查找算法)。 思路:以数组某个值为界,再递归进行查找,直到结束。 <?phpfunction find($array, $low, $high, $k){ if ($low <= $high){ $mid = intval(($low+$high)/2); if ($array[$mid] == $k){ return $mid; }elseif ($k < $array[$mid]){ return find($array, $low, $mid-1, $k); }else{ return find($array, $mid+1, $high, $k); } } die('Not have...');} //test$array = array(2,4,3,5);$n = count($array);$r = find($array,0,$n, 7、合并多个数组,不用array_merge(),题目来于论坛。 思路:遍历每个数组,重新组成一个新数组。 <?phpfunction t(){ $c = func_num_args()-1; $a = func_get_args(); //print_r($a); for($i=0; $i<=$c; $i++){ if(is_array($a[$i])){ for($j=0; $j<count($a[$i]); $j++){ $r[] = $a[$i][$j]; } } else { die('Not a array!'); } } return $r;} //testprint_r(t(range(1,4),range(1,4),range(1,4)));echo '<br/>';$a = array_merge(range(1,4),range(1,4),range(1,4));print_r($a); 8、牛年求牛:有一母牛,到4岁可生育,每年一头,所生均是一样的母牛,到15岁绝育,不再能生,20岁死亡,问n年后有多少头牛。(来自论坛) <?phpfunction t($n) { static $num = 1 for($j=1; $j<=$n; $j++){ if($j>=4 && $j<15) {$num++;t($n-$j);} if($j==20){$num--;} } return $num;} //testecho t(8);

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值