PHP实现经典算法(下)

下面我们来实现下列算法

  • 堆排序
  • 鸡尾酒排序
  • 直接选择排序
  • 计数排序
代码如下:

$arr = [];

for ($i = 0; $i < 5000; $i++) {
    $arr[] = rand(1, 50000);
}



// 5 堆排序

/**
 * 交换两个数的位置
 * @param $a
 * @param $b
 */
function swap(&$a,&$b){
    $temp = $b;
    $b = $a;
    $a = $temp;
}

/**
 * 左子树
 * @param $i
 * @return mixed
 */
function lchild($i){ return $i*2+1;}

/**
 * 右子树
 * @param $i
 * @return mixed
 */
function rchild($i){ return $i*2+2;}

/**
 * 整理节点
 * @param $array 待调整的堆数组
 * @param $i 待调整的数组元素的位置
 * @param $heapsize  数组的长度
 */
function build_heap(&$array,$i,$heapsize){

    $left = lchild($i);
    $right = rchild($i);
    $max = $i;
    //如果比左子树小并且在左右子树的右面,边界调整到左侧
    if($i < $heapsize && $left < $heapsize  && $array[$left] > $array[$i] ){
        $max = $left;
    }

    //如果比右子树小并且都小于要构建的数组长度,边界调整到右侧
    if($i < $heapsize && $right < $heapsize && $array[$right] > $array[$max]){
        $max = $right;
    }

    //如果经过两次调整后,要调整的数组不是最大值
    if($i != $max && $i < $heapsize && $max < $heapsize){

        //就交换对应的位置,并再次进行整理节点
        swap($array[$i],$array[$max]);
        build_heap($array,$max,$heapsize);

    }
}

/**
 * 对堆进行排序
 * @param $array 要排序的数组
 * @param $heapsize 数组的长度
 */
function sortHeap(&$array,$heapsize){
    while($heapsize){ //长度逐步递减0

        //首先交换第一个元素和最后一个元素的位置
        swap($array[0],$array[$heapsize-1]);
        $heapsize = $heapsize -1;
        build_heap($array,0,$heapsize); //整理数组的第一个的元素的位置,长度为逐步递减的数组长度
    }
}

/**
 * 创建堆
 * @param $array
 * @param $heapsize
 */
function createHeap(&$array,$heapsize){
    $i = ceil($heapsize/2)-1; //找到中间的位置
    for( ; $i>=0 ;$i-- ){  //从中间往前面整理堆
        build_heap($array,$i,$heapsize);
    }
}

/**
 * 堆排序主函数
 */
function Heapsort($array){
    $heapsize = count($array);
    createHeap($array,$heapsize);
    sortHeap($array,$heapsize);

    return $array;

}



$heapsort_start_time = microtime(true);

$heapsort_sort = Heapsort($arr);

$heapsort_end_time = microtime(true);

$heapsort_need_time = $heapsort_end_time - $heapsort_start_time;

print_r("堆排序耗时:" . $heapsort_need_time . "<br />");


// 6 鸡尾酒排序法

/**
 * 鸡尾酒排序
 * @param $arr
 * @return mixed
 */
function Cocktailsort($arr) {
    $arr_len  =count($arr);

    for($i = 0 ; $i < ($arr_len/2) ; $i ++){
        //将最小值排到队尾
        for( $j = $i ; $j < ( $arr_len - $i - 1 ) ; $j ++ ){
            if($arr[$j] < $arr[$j + 1] ){
                swap($arr[$j],$arr[$j + 1]);
            }
        }
        //将最大值排到队头
        for($j = $arr_len - 1 - ($i + 1); $j > $i ; $j --){
            if($arr[$j] > $arr[$j - 1]){
                swap($arr[$j],$arr[$j - 1]);
            }
        }
    }
    return $arr;
}

$cocktailsort_start_time = microtime(true);

$cocktailsort_sort = Cocktailsort($arr);

$cocktailsortt_end_time = microtime(true);

$cocktailsort_need_time = $cocktailsortt_end_time - $cocktailsort_start_time;

print_r("鸡尾酒排序耗时:" . $cocktailsort_need_time . "<br />");


// 7  希尔排序

/**
 * 希尔排序
 * @param $arr
 */
function Shellsort($arr)
{
    $n=count($arr); //数组长度

    for($gap=floor($n/2);$gap>0;$gap=floor($gap/=2)) //
    {
        for($i=$gap;$i<$n;++$i) //根据增量循环
        {
            //以增量为步幅进行查看
            for( $j=$i-$gap; $j>=0 && $arr[$j+$gap] < $arr[$j]; $j -= $gap)
            {
                swap($arr[$j],$arr[$j+$gap]);
            }
        }
    }

    return $arr;
}

$shellsort_start_time = microtime(true);

$shellsort_sort = Cocktailsort($arr);

$shellsort_end_time = microtime(true);

$shellsort_need_time = $shellsort_end_time - $shellsort_start_time;

print_r("希尔排序耗时:" . $shellsort_need_time . "<br />");

// 8  直接选择排序

/**
 * 直接选择排序
 * @param $arr
 * @return mixed
 */
function  Straightselectsort($arr){

    $n = count($arr);

    for($i = 0 ; $i < $n - 1;$i++){
        $m = $i;
        for($j = $i+1 ; $j < $n; $j++){
            if($arr[$j] < $arr[$m] ){
                $m = $j;
            }

            if($m != $j){
                //进行交换
                swap($arr[$m],$arr[$j]);
            }
        }
    }
    return $arr;
}

$straightselectsort_start_time = microtime(true);

$straightselectsort_sort = Cocktailsort($arr);

$straightselectsort_end_time = microtime(true);

$straightselectsort_need_time = $straightselectsort_end_time - $straightselectsort_start_time;

print_r("直接选择排序耗时:" . $straightselectsort_need_time . "<br />");


// 9  计数排序

/**
 * 计数排序
 * @param $arr
 * @return mixed
 */
function Countsort($arr){

    $max = $arr[0];
    $min = $arr[0];

    foreach($arr as $key => $value) {
        if ($value > $max) {
            $max = $value;
        }
        if ($value < $min) {
            $min = $value;
        }
    }
        //这里k的大小是要排序的数组中,元素大小的极值差+1
        $c=[];
        $k = $max - $min + 1;
        for($i = 0; $i < count($arr) ; $i ++){
            $c[$arr[$i] - $min ] +=1;
        }

        for($i=1;$i < count($c); ++$i){
            $c[$i] = $c[$i] + $c[$i - 1];
        }

        for($i = count($arr);$i > 0 ; --$i){
            $b[ -- $c[$arr[$i] - $min] ] = $arr[$i];
        }

    return $b;
}

$countsort_start_time = microtime(true);

$countsort_sort = Cocktailsort($arr);

$countsort_end_time = microtime(true);

$countsort_need_time = $countsort_end_time - $countsort_start_time;

print_r("计数排序耗时:" . $countsort_need_time . "<br />");

耗时对比

堆排序耗时:0.086709976196289 
鸡尾酒排序耗时:4.6467659473419 
希尔排序耗时:4.4215688705444 
直接选择排序耗时:4.529422044754 
计数排序耗时:4.2601070404053



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 蒙特卡洛算法是一种通过重复随机抽样来估算数学期望值的方法。在PHP实现蒙特卡洛算法可以使用随机数生成函数,如mt_rand()或rand(),来生成随机样本。然后计算这些样本的平均值来估算数学期望值。 示例代码: ``` function monte_carlo($samples) { $sum = 0; for ($i = 0; $i < $samples; $i++) { $x = mt_rand(0, 100) / 100; $y = mt_rand(0, 100) / 100; $sum += $x * $y; } return $sum / $samples; } $samples = 10000; $result = monte_carlo($samples); echo "Estimated value: " . $result; ``` 上面这段代码使用了10000个随机样本来估算 x * y 的数学期望值。 请注意:这只是一个简单的示例代码,实际上蒙特卡洛算法的应用场景和方法更加复杂。 ### 回答2: 蒙特卡洛算法是一种基于概率统计的方法,常用于解决复杂问题的数值计算。它通过大量的随机模拟实验来近似计算问题的解。下面我将用300字中文来解释如何使用PHP实现蒙特卡洛算法。 首先,我们需要确定要解决的问题。蒙特卡洛算法可以用于很多问题,如求解复杂积分、计算π的近似值等。假设我们要用蒙特卡洛算法来估计一个圆的面积。 首先,我们需要设置实验次数n,即模拟抛点的次数。然后,我们需要编写一个函数来判断一个点是否在圆内。这可以通过计算点到圆心的距离是否小于半径来实现。 接下来,我们可以使用PHP的随机数函数来产生随机点的坐标。我们可以使用rand()函数来生成一个0到1之间的随机数,分别作为x和y坐标。然后,我们调用判断点是否在圆内的函数来判断这个点是否落在圆内。 重复以上步骤n次,得到落在圆内的点的个数m。最后,我们可以通过以下公式来估计圆的面积:面积 = (4 * m) / n。 最后,我们可以将上述操作封装为一个函数,并根据需要调用该函数来得到圆的面积估计值。 在编写代码时,我们需要注意随机数生成的质量,以及设置合适的实验次数n来得到较为准确的估计结果。此外,我们也可以通过增加模拟实验的次数n,来提高计算结果的准确性。 通过上述步骤,我们可以用PHP实现蒙特卡洛算法来估计圆的面积。当然,蒙特卡洛算法还可以用于其他的问题求解,只需要根据不同的问题确定判断点是否在目标区域内的方法即可。 ### 回答3: 蒙特卡洛算法是一种通过随机模拟来解决问题的数值方法。使用PHP编写蒙特卡洛算法可以实现对一些问题的近似求解。 首先,我们需要明确要解决的问题。以估算圆周率π为例,我们可以通过蒙特卡洛算法来近似计算。 在PHP中,我们可以编写一个函数来实现蒙特卡洛算法。函数代码如下: ```php function estimatePi($numPoints) { $pointsInside = 0; for ($i = 0; $i < $numPoints; $i++) { $x = rand(-1, 1); $y = rand(-1, 1); if (($x * $x + $y * $y) <= 1) { $pointsInside++; } } return 4 * $pointsInside / $numPoints; } ``` 在这个函数中,我们使用rand()函数生成一个在[-1, 1]范围内的随机数作为点的横坐标和纵坐标。然后,我们判断该点是否在单位圆的内部(即点到原点的距离是否小于等于1),如果在内部,则计数器$pointsInside加1。 最后返回估算得到的π值,公式为4 * 内部点计数器 / 总点数。 我们可以调用这个函数来进行估算,示例代码如下: ```php $numPoints = 1000000; // 设置总点数 $estimatedPi = estimatePi($numPoints); echo "Estimated Pi: " . $estimatedPi; ``` 在这个例子中,我们设置总点数为1000000,然后调用estimatePi()函数进行估算得到π的近似值,最后输出结果。 通过以上的方式,我们便可以使用PHP实现蒙特卡洛算法,并得到对问题的近似解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值