php常见算法一览(不定期更新中......)

二分法查找元素:

function binarySearch($arr, $target) {
    $left = 0;
    $right = count($arr) - 1;
    
    while ($left <= $right) {
        $mid = floor(($left + $right) / 2);
        if ($arr[$mid] == $target) {
            return $mid; // 找到目标值,返回索引
        }
        if ($arr[$mid] < $target) {
            $left = $mid + 1; // 目标值在右侧,更新左边界
        } else {
            $right = $mid - 1; // 目标值在左侧,更新右边界
        }
    }
    
    return -1; // 目标值不存在,返回-1
}

准备一个有序数组:
$nums = [2, 5, 8, 12, 16, 23, 38, 45, 57, 68];
$target = 16; // 假设目标值是数组里的16
$result = binarySearch($nums, $target);
if ($result == -1) {
    echo "目标值 $target 不存在于数组中。";
} else {
    echo "目标值 $target 的索引为 $result。";
}

首先定义了一个binarySearch函数来执行二分搜索算法。函数接受两个参数:一个有序数组$arr和要搜索的目标值$target。函数使用两个指针$left$right来表示搜索范围的边界,并在每次迭代中将搜索范围缩小一半。如果找到目标值,则返回目标值的索引;如果目标值不存在,则返回-1。注意,二分搜索算法要求在有序数组上进行操作。

冒泡排序:

function bubbleSort($arr) {
    $n = count($arr);
    // 外层循环控制比较轮数
    for ($i = 0; $i < $n - 1; $i++) {
        // 内层循环执行每轮比较
        for ($j = 0; $j < $n - $i - 1; $j++) {
            // 如果当前元素大于下一个元素,则交换它们
            if ($arr[$j] > $arr[$j + 1]) {
                $temp = $arr[$j];
                $arr[$j] = $arr[$j + 1];
                $arr[$j + 1] = $temp;
            }
        }
    }

    return $arr;
}

// 示例用法
$unsortedArray = [64, 34, 25, 12, 22, 11, 90];
$sortedArray = bubbleSort($unsortedArray);
echo "排序后的数组:";
print_r($sortedArray);

定义了一个bubbleSort函数,接受一个待排序的数组作为参数,并返回排序后的数组。外层循环用于控制比较轮数,内层循环用于执行每轮比较并交换元素。在每一轮内层循环结束后,最大的元素都会浮到数组的末尾,因此外层循环的轮数逐渐减少,直到排序完成。

以上是冒泡排序算法的PHP实现示例。请注意,冒泡排序不是最有效的排序算法,特别是对于大型数据集,因为它的时间复杂度为O(n^2)。在实际应用中,更常用的排序算法是快速排序、归并排序或使用PHP内置的sort函数。

桶排序:

function bucketSort($arr) {
    // 找到数组中的最大值和最小值
    $min = min($arr);
    $max = max($arr);
    // 计算桶的数量,这里可以根据实际情况调整桶的数量
    $bucketCount = ($max - $min) + 1;
    // 创建桶并初始化为空数组
    $buckets = array_fill(0, $bucketCount, []);
    // 将元素分配到桶中
    foreach ($arr as $num) {
        $index = $num - $min; // 计算桶的索引
        array_push($buckets[$index], $num);
    }
    // 对每个桶中的元素进行排序
    foreach ($buckets as &$bucket) {
        sort($bucket);
    }
    // 合并桶中的数据以获得最终排序结果
    $sortedArray = [];
    foreach ($buckets as $bucket) {
        $sortedArray = array_merge($sortedArray, $bucket);
    }

    return $sortedArray;
}

// 示例用法
$unsortedArray = [64, 34, 25, 12, 22, 11, 90];
$sortedArray = bucketSort($unsortedArray);
echo "排序后的数组:";
print_r($sortedArray);

首先找到了输入数组中的最小值和最大值,然后根据这两个值计算了桶的数量。接下来,我们创建了一个桶的数组,每个桶是一个空数组。

然后,我们遍历输入数组中的每个元素,将每个元素放入相应的桶中。为了确定元素应该放入哪个桶,我们使用了元素值与最小值之差作为桶的索引。

接着,我们对每个桶中的元素进行排序,这里使用了PHP的sort函数。

最后,我们将每个桶中的元素按照桶的顺序合并成最终的排序结果。

需要注意的是,桶排序适用于数据分布均匀的情况,如果数据分布不均匀,可能需要进行一些额外的优化。此外,桶排序的性能也取决于桶的数量的选择,需要根据具体情况进行调整。

快速排序:

function quickSort($arr) {
    // 如果数组为空或只包含一个元素,直接返回
    if (count($arr) <= 1) {
        return $arr;
    }
    // 选择一个基准元素
    $pivot = $arr[0];
    $left = $right = [];
    // 将小于基准的元素放入左子数组,大于基准的元素放入右子数组
    for ($i = 1; $i < count($arr); $i++) {
        if ($arr[$i] < $pivot) {
            $left[] = $arr[$i];
        } else {
            $right[] = $arr[$i];
        }
    }
    // 递归地对左右子数组进行排序,并合并结果
    return array_merge(quickSort($left), [$pivot], quickSort($right));
}

// 示例用法
$unsortedArray = [64, 34, 25, 12, 22, 11, 90];
$sortedArray = quickSort($unsortedArray);
echo "排序后的数组:";
print_r($sortedArray);

算法的基本思想是选择一个基准元素,将数组分成两个子数组,一个包含小于基准元素的元素,另一个包含大于基准元素的元素,然后递归地对这两个子数组进行排序。

quickSort函数首先检查输入数组是否为空或只包含一个元素,如果是,则直接返回数组。然后,选择一个基准元素(通常是第一个元素),将小于基准的元素放入左子数组,大于基准的元素放入右子数组。接下来,递归地对左右子数组进行排序,然后将排序后的左子数组、基准元素和排序后的右子数组合并成最终的排序结果。

快速排序的时间复杂度平均情况下为O(n log n),它是一种非常高效的排序算法,通常用于大规模数据集的排序。在实际应用中,也可以采用不同的方式选择基准元素,以优化算法的性能。

递归算法:

示例1:计算阶乘
function factorial($n) {
    if ($n <= 1) {
        return 1;
    } else {
        return $n * factorial($n - 1);
    }
}
// 示例用法
$result = factorial(5);
echo "5的阶乘是:" . $result; // 输出 120

示例2:计算斐波那契数列的第n个数
function fibonacci($n) {
    if ($n <= 0) {
        return 0;
    } elseif ($n == 1) {
        return 1;
    } else {
        return fibonacci($n - 1) + fibonacci($n - 2);
    }
}
// 示例用法
$result = fibonacci(6);
echo "斐波那契数列的第6个数是:" . $result; // 输出 8

递归是一种在函数内部调用自身的编程技巧。它通常用于解决问题,这些问题可以分解成更小的子问题,然后通过递归调用来解决这些子问题。

在这个示例中,factorial函数计算一个正整数的阶乘。如果输入值$n小于或等于1,则返回1(递归的终止条件)。否则,函数调用自身,传递$n - 1作为参数,并将结果乘以$n。这样,递归将一直进行,直到$n减小到1,然后递归终止。

递归是一个强大的编程技巧,但需要小心处理递归终止条件,以避免无限递归导致堆栈溢出。

递归实现无限级分类:

function categoryTree($categories, $parentId = 0) {
    $newTree = [];
    
    foreach ($categories as $item) {
        if ($item['parent_id'] == $parentId) {
            $child = categoryTree($categories, $item['id']);
            if ($child) {
                $item['child'] = $child;
            }
            $newTree[] = $item;
        }
    }
    
    return $newTree;
}

$categories = array(
    ['id' => 1, 'name' => '电子产品', 'parent_id' => 0],
    ['id' => 2, 'name' => '手机', 'parent_id' => 1],
    ['id' => 3, 'name' => '电视', 'parent_id' => 1],
    ['id' => 4, 'name' => '苹果手机', 'parent_id' => 2],
    ['id' => 5, 'name' => '三星手机', 'parent_id' => 2],
    ['id' => 6, 'name' => '家具产品', 'parent_id' => 0],
    // 更多分类...
);

$tree = categoryTree($categories);

无限极分类通常是指一个数据结构,其中每个分类可以包含子分类,子分类也可以包含子分类,以此类推。

上述函数会遍历分类数组,找到所有具有给定父分类ID的分类,并将它们递归地添加到一个子分类数组中。最终,它会返回一个包含所有分类的树状结构。

  • 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、付费专栏及课程。

余额充值