PHP 算法 排序

这里是用PHP写的几个基础算法,经典名句:算法+数据结构=程序。如果你想成为真正的程序员,请好好学C,学好数据结构与算 法。
1、首先来画个菱形玩玩,很多人学C时在书上都画过,咱们用PHP画下,画了一半。
思路:多少行for一次,然后在里面空格和星号for一次。

<?php
for($i=0;$i<=3;$i++){
    echo str_repeat("&nbsp;",3-$i);
    echo str_repeat("*",$i*2+1);
    echo '<br/>';       
}
?>

2、杨辉三角,用PHP写。

思路:每一行的第一位和最后一位是1,没有变化,中间是前排一位与左边一排的和,这种算法是用一个二维数组保存,另外有种算法用一维数组也可以实现,一行 一行的输出,有兴趣去写着玩下。
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 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].'&nbsp;';
    }
    echo '<br/>';
  }
 ?>

==========================================================================================

php常用的四大基本算法

1、插 入排序:

【基本思想】:每次将一个待排序的数据元素,插入到前面已经排好序的数列中的适当位置,使数列依然有序;直到待排序数据元素 全部插入完为止。
思路分析:在要排序的一组数中,假设前面的数已经是排好顺序的,现在要把第n个数插到前面的
有序数中,使得这n个数也是排好顺序的。如此反复循环,直到全部排好顺序。
【示例】:
[初始关键字] [49] 38 65 97 76 13 27 49
J=2(38) [38 49] 65 97 76 13 27 49
J=3(65) [38 49 65] 97 76 13 27 49
J=4(97) [38 49 65 97] 76 13 27 49
J=5(76) [38 49 65 76 97] 13 27 49
J=6(13) [13 38 49 65 76 97] 27 49
J=7(27) [13 27 38 49 65 76 97] 49
J=8(49) [13 27 38 49 49 65 76 97]

<?php
/*第一种*/
function insert_sort($arr){
$count = count($arr);
for($i=1; $i<$count; $i++){
    $tmp = $arr[$i];
    $j = $i - 1;
    while($arr[$j] > $tmp){
      $arr[$j+1] = $arr[$j];
      $arr[$j] = $tmp;
      $j--;
    }
}
return $arr;
}
/*第二种*/
function insertSort($arr) {
    $len=count($arr); 
    for($i=1, $i<$len; $i++) {
        $tmp = $arr[$i];
        //内层循环控制,比较并插入
        for($j=$i-1;$j>=0;$j--) {
            if($tmp < $arr[$j]) {
                //发现插入的元素要小,交换位置,将后边的元素与前面的元素互换
                $arr[$j+1] = $arr[$j];
                $arr[$j] = $tmp;
            } else {
                //如果碰到不需要移动的元素,由于是已经排序好是数组,则前面的就不需要再次比较了。
                break;
            }
        }
    }
    return $arr;
}
?>

2、选择排序:

【基 本思想①】:每一趟从待排序的数据元素中选出最小(或最大)的一个元素,顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。

思路分析②:在要排序的一组数中,选出最小的一个数与第一个位置的数交换。然后在剩下的数当中
再找最小的与第二个位置的数交换,如此循环到倒数第二个数和最后一个数比较为止。
代码实现:
【示例】:
[初 始关键字] [49 38 65 97 76 13 27 49]
第一趟排序后 13 [38 65 97 76 49 27 49]
第 二趟排序后 13 27 [65 97 76 49 38 49]
第三趟排序后 13 27 38 [97 76 49 65 49]
第 四趟排序后 13 27 38 49 [49 97 65 76]
第五趟排序后 13 27 38 49 49 [97 97 76]
第 六趟排序后 13 27 38 49 49 76 [76 97]
第七趟排序后 13 27 38 49 49 76 76 [ 97]
最 后排序结果 13 27 38 49 49 76 76 97

<?php
/*第一种*/
function select_sort($arr){
$count = count($arr);
for($i=0; $i<$count; $i++){
    $k = $i;
    for($j=$i+1; $j<$count; $j++){
        if ($arr[$k] > $arr[$j])
           $k = $j;
}
    if($k != $i){
        $tmp = $arr[$i];
        $arr[$i] = $arr[$k];
        $arr[$k] = $tmp;
    }
}
return $arr;
}
/*第二种*/
function selectSort($arr) {
//双重循环完成,外层控制轮数,内层控制比较次数
 $len=count($arr);
    for($i=0; $i<$len-1; $i++) {
        //先假设最小的值的位置
        $p = $i;

        for($j=$i+1; $j<$len; $j++) {
            //$arr[$p] 是当前已知的最小值
            if($arr[$p] > $arr[$j]) {
            //比较,发现更小的,记录下最小值的位置;并且在下次比较时采用已知的最小值进行比较。
                $p = $j;
            }
        }
        //已经确定了当前的最小值的位置,保存到$p中。如果发现最小值的位置与当前假设的位置$i不同,
        //则位置互换即可。
        if($p != $i) {
            $tmp = $arr[$p];
            $arr[$p] = $arr[$i];
            $arr[$i] = $tmp;
        }
    }
    //返回最终结果
    return $arr;
}
?>

3、冒泡排序:

【基本思想①】:两两比较待排序数据元素的大小,发现两个数据元素的次序 相反时即进行交换,直到没有反序的数据元素为止。
【排序过程】:设想被排序的数组R[1..N]垂直竖立,将每个数据元素看作有重量的气泡,根据 轻气泡不能在重气泡之下的原则,
从下往上扫描数组R,凡扫描到违反本原则的轻气泡,就使其向上”漂浮”,如此反复进行,直至最后任何两个气泡都是 轻者在上,重者在下为止。

思路分析②:在要排序的一组数中,对当前还未排好的序列,从前往后对相邻的两个数依次进行比较
和调整,让较大的数往下沉,较小的往上冒。即,每当两相邻的数比较后发现它们的排序与排序要
求相反时,就将它们互换。
【示例】:
49 13 13 13 13 13 13 13
38 49 27 27 27 27 27 27
65 38 49 38 38 38 38 38
97 65 38 49 49 49 49 49
76 97 65 49 49 49 49 49
13 76 97 65 65 65 65 65
27 27 76 97 76 76 76 76
49 49 49 76 97 97 97 97

<?php
/*第一种*/
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 bubbleSort($arr){  
  $len=count($arr);
  //该层循环控制 需要冒泡的轮数
  for($i=1;$i<$len;$i++){ //该层循环用来控制每轮 冒出一个数 需要比较的次数
    for($k=0;$k<$len-$i;$k++) {
       if($arr[$k]>$arr[$k+1]){
            $tmp=$arr[$k+1];
            $arr[$k+1]=$arr[$k];
            $arr[$k]=$tmp;
        }
    }
  }
  return $arr;
}
?>

4、快速排序:

【基本思想①】:在当前无序区R[1..H]中任取一个数据元素作为比较的”基准”(不妨记为X),
用此基准将当前无序区划分为 左右两个较小的无序区:R[1..I-1]和R[I 1..H],且左边的无序子区中数据元素均小于等于基准元素,
右边的无序子区中数据元素均大 于等于基准元素,而基准X则位于最终排序的位置上,即R[1..I-1]≤X.Key≤RI 1..H
当R[1..I-1] 和R[I 1..H]均非空时,分别对它们进行上述的划分过程,直至所有无序子区中的数据元素均已排序为止。

思路分析②:选择一个基准元素,通常选择第一个元素或者最后一个元素。通过一趟扫描,将待排序列
分成两部分,一部分比基准元素小,一部分大于等于基准元素。此时基准元素在其排好序后的正确位置
,然后再用同样的方法递归地排序划分的两部分。
【示例】:
初始关键字 [49 38 65 97 76 13 27 49]
第一次交换后 [27 38 65 97 76 13 49 49]
第二次交换后 [27 38 49 97 76 13 65 49]
J向左扫描,位置不变,第三次交换后 [27 38 13 97 76 49 65 49]
I向右扫描,位置不变,第四次交换后 [27 38 13 49 76 97 65 49]
J向左扫描 [27 38 13 49 76 97 65 49]
(一次划分过程)

初始关键字 [49 38 65 97 76 13 27 49]
一趟排序之后 [27 38 13] 49 [76 97 65 49]
二趟排序之后 [13] 27 [38] 49 [49 65]76 [97]
三趟排序之后 13 27 38 49 49 [65]76 97
最后的排序结果 13 27 38 49 49 65 76 97
各趟排序之后的状态

<?php
/*第一种*/
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); 
}
/*第二种*/
function quickSort($arr) {
    //先判断是否需要继续进行
    $length = count($arr);
    if($length <= 1) {
        return $arr;
    }
    //选择第一个元素作为基准
    $base_num = $arr[0];
    //遍历除了标尺外的所有元素,按照大小关系放入两个数组内
    //初始化两个数组
    $left_array = array();  //小于基准的
    $right_array = array();  //大于基准的
    for($i=1; $i<$length; $i++) {
        if($base_num > $arr[$i]) {
            //放入左边数组
            $left_array[] = $arr[$i];
        } else {
            //放入右边
            $right_array[] = $arr[$i];
        }
    }
    //再分别对左边和右边的数组进行相同的排序处理方式递归调用这个函数
    $left_array = quick_sort($left_array);
    $right_array = quick_sort($right_array);
    //合并
    return array_merge($left_array, array($base_num), $right_array);
}

/*打印数组全部内容*/
function display_arr($array){
$len = count($array);
for($i = 0; $i<$len; $i++){
   echo $array[$i].' ';
}
echo '<br />';
}
?>

==========================================================================================
牛年求牛:有一母牛,到4岁可生育,每年一头,所生均是一样的母牛,到15岁绝育,不再能生,20岁死亡,问n年后有多少头牛。

冒泡排序:两两交换数值,最小的值在最左边,就如最轻的气泡在最上边。对整列数两两交换一次,最小的数在最左边,每次都能得一个在剩下的数中的最小 的数,“冒”出来的数组成一个有序区间,剩下的值组成一无序区间,且有序区间中每一元素值都比无序区间的小。

快速排序:基准数,左右二个数组,递归调用,合并。

插入排序:排序区间分成二部分,左边有序,右边无序,从右区间取第一个元素插入左区间,若此元素比左边区间最右边的元素大,留在原处,若此元素比左 边区间最右边的元素小,则插在最右边元素的原位置,同时最右边元素右移一位,计算器减一,重新和前面的元素比较,直到前面的元素比要插入元素小为止,重复 上述步骤。

注意区间端点值的处理,及数组的第一个元素下标为0.

===================================================================================

PHP九九乘法表

这里写图片描述

<?php  
    echo '<table border="1" >';
    for($i=1;$i<=9;$i++){
        echo '<tr>';
        for($j=1;$j<=$i;$j++){
            echo '<td>'.$j.'x'.$i.'='.$i*$j.'</td>';
        }
        echo '</tr>';
    }
    echo '</table>';
?>

二分查找算法。

思路:以数组中某个值为界,再递归进行查找,直到结束。

<?php
function 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,5)
?>

1、排列组合

/**
* 采用二进制方法进行组合的选择,如表示5选3时,只需有3位为1就可以了,所以可得到的组合是 01101 11100 00111 10011 01110等10种组合
* @param 需要排列的数组 arr@param min_size
* @return 满足条件的新数组组合
*/

<?php
function pl($arr,$size=5) {
  $len = count($arr);
  $max = pow(2,$len);
  $min = pow(2,$size)-1;
  $r_arr = array();
  for ($i=$min; $i<$max; $i++){
   $count = 0;
   $t_arr = array();
   for ($j=0; $j<$len; $j++){
    $a = pow(2, $j);
    $t = $i&$a;
    if($t == $a){
     $t_arr[] = $arr[$j];
     $count++;
    }
   }   
   if($count == $size){
    $r_arr[] = $t_arr;    
   }   
  }
  return $r_arr;
 }
$pl = pl(array(1,2,3,4,5,6,7),5);
var_dump($pl);
?>

2、递归算法 阶乘

<?php
function f($n){   
    if($n == 1 || $n == 0){
        return 1;
    }else{
        return $n*f($n-1);
    }
}
echo f(5);
?>

3、遍历目录

<?php
function iteral($path){
    $filearr = array();
    foreach (glob($path.'\*') as $file){
        if(is_dir($file)){
            $filearr = array_merge($filearr,iteral($file));
        }else{
            $filearr[] = $file;
        }
    }
    return $filearr;
}
var_dump(iteral('d:\www\test'));
?>

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=

数组应用

合并多个数组,不用array_merge()。

思路:遍历每个数组,重新组成一个新数组。

<?php
function 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;
}
//test
print_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);
?>

推荐链接:GIF演示排序算法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值