PHP经典算法集锦【经典收藏】
本文实例总结了PHP经典算法。分享给大家供大家参考,具体如下:
1、首先来画个菱形玩玩,很多人学C时在书上都画过,咱们用PHP画下,画了一半。
思路:多少行for一次,然后在里面空格和星号for一次。
<?php
for($i=0;$i<=3;$i++){
echostr_repeat(" ",3-$i);
echostr_repeat("*",$i*2+1);
echo'<br/>';
}
2、冒泡排序,C里基础算法,从小到大对一组数排序。
思路:这题从小到大,第一轮排最小,第二轮排第二小,第三轮排第三小,依次类推……
<?php
$arr=array(1,3,5,32,756,2,6);
$len=count($arr);
for($i=0;$i<$len-1;$i++){
for($j=$i+1;$j<$len;$j++){
if($arr[$i]>$arr[$j]){//从小到大
$p=$arr[$i];
$arr[$i]=$arr[$j];
$arr[$j]=$p;
}
}
}
var_dump($arr);
3、杨辉三角,用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].' ';
}
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、对一组数进行排序(快速排序算法)。
思路:通过一趟排序分成两部分,然后递归对这两部分排序,最后合并。
<?php
functionq($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);
returnarray_merge($l,array($key),$r);
}
$arr=array(1,2,44,3,4,33);
print_r(q($arr));
6、在一个数组查找你所需元素(二分查找算法)。
思路:以数组中某个值为界,再递归进行查找,直到结束。
<?php
functionfind($array,$low,$high,$k){
if($low<=$high){
$mid=intval(($low+$high)/2);
if($array[$mid]==$k){
return$mid;
}elseif($k<$array[$mid]){
returnfind($array,$low,$mid-1,$k);
}else{
returnfind($array,$mid+1,$high,$k);
}
}
die('Nothave...');
}
//test
$array=array(2,4,3,5);
$n=count($array);
$r=find($array,0,$n,5)
7、合并多个数组,不用array_merge(),题目来于论坛。
思路:遍历每个数组,重新组成一个新数组。
<?php
functiont(){
$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('Notaarray!');
}
}
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);
8、牛年求牛:有一母牛,到4岁可生育,每年一头,所生均是一样的母牛,到15岁绝育,不再能生,20岁死亡,问n年后有多少头牛。(来自论坛)
<?php
functiont($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;
}
//test
echot(8);
====================其他算法=========================
冒泡排序(bubblesort)—O(n2)
$data=array(3,5,9,32,2,1,2,1,8,5);
dump($data);
BubbleSort($data);
dump($data);
functionBubbleSort(&$arr)
{
$limit=count($arr);
for($i=1;$i<$limit;$i++)
{
for($p=$limit-1;$p>=$i;$p--)
{
if($arr[$p-1]>$arr[$p])
{
$temp=$arr[$p-1];
$arr[$p-1]=$arr[$p];
$arr[$p]=$temp;
}
}
}
}
functiondump($d)
{
echo'<pre>';
print_r($d);
echo'</pre>';
}
插入排序 (insertionsort)—O(n2)
$data=array(6,13,21,99,18,2,25,33,19,84);
$nums=count($data)-1;
dump($data);
InsertionSort($data,$nums);
dump($data);
functionInsertionSort(&$arr,$n)
{
for($i=1;$i<=$n;$i++)
{
$tmp=$arr[$i];
for($j=$i;$j>0&&$arr[$j-1]>$tmp;$j--)
{
$arr[$j]=$arr[$j-1];
}
$arr[$j]=$tmp;
}
}
functiondump($d)
{
echo'<pre>';print_r($d);echo'</pre>';
}
希尔排序 (shellsort)—O(nlogn)
$data=array(6,13,21,99,18,2,25,33,19,84);
$nums=count($data);
dump($data);
ShellSort($data,$nums);
dump($data);
functionShellSort(&$arr,$n)
{
for($increment=intval($n/2);$increment>0;$increment=intval($increment/2))
{
for($i=$increment;$i<$n;$i++)
{
$tmp=$arr[$i];
for($j=$i;$j>=$increment;$j-=$increment)
if($tmp<$arr[$j-$increment])
$arr[$j]=$arr[$j-$increment];
else
break;
$arr[$j]=$tmp;
}
}
}
functiondump($d)
{
echo'<pre>';print_r($d);echo'</pre>';
}
快速排序 (quicksort)—O(nlogn)
$data=array(6,13,21,99,18,2,25,33,19,84);
dump($data);
quicks($data,0,count($data)-1);
dump($data);
functiondump($data){
echo'<pre>';print_r($data);echo'</pre>';
}
functionQuickSort(&$arr,$left,$right)
{
$l=$left;
$r=$right;
$pivot=intval(($r+$l)/2);
$p=$arr[$pivot];
do
{
while(($arr[$l]<$p)&&($l<$right))
$l++;
while(($arr[$r]>$p)&&($r>$left))
$r--;
if($l<=$r)
{
$temp=$arr[$l];
$arr[$l]=$arr[$r];
$arr[$r]=$temp;
$l++;
$r--;
}
}
while($l<=$r);
if($left<$r)
QuickSort(&$arr,$left,$r);
if($l<$right)
QuickSort(&$arr,$l,$right);
}
=================================================
冒泡排序:两两交换数值,最小的值在最左边,就如最轻的气泡在最上边。对整列数两两交换一次,最小的数在最左边,每次都能得一个在剩下的数中的最小的数,“冒”出来的数组成一个有序区间,剩下的值组成一无序区间,且有序区间中每一元素值都比无序区间的小。
快速排序:基准数,左右二个数组,递归调用,合并。
插入排序:排序区间分成二部分,左边有序,右边无序,从右区间取第一个元素插入左区间,若此元素比左边区间最右边的元素大,留在原处,若此元素比左边区间最右边的元素小,则插在最右边元素的原位置,同时最右边元素右移一位,计算器减一,重新和前面的元素比较,直到前面的元素比要插入元素小为止,重复上述步骤。
注意区间端点值的处理,及数组的第一个元素下标为0.
<?php
//PHP常用排序算法
functionbubblesort($array)
{
$n=count($array);
for($i=0;$i<$n;$i++)
{
for($j=$n-2;$j>=$i;$j--)//[0,i-1][i,n-1]
{
if($array[$j]>$array[$j+1])
{
$temp=$array[$j];
$array[$j]=$array[$j+1];
$array[$j+1]=$temp;
}
}
}
return$array;
}
$array=array(3,6,1,5,9,0,4,6,11);
print_r(bubblesort($array));
echo'<hr>';
functionquicksort($array)
{
$n=count($array);
if($n<=1)
{
return$array;
}
$key=$array['0'];
$array_r=array();
$array_l=array();
for($i=1;$i<$n;$i++)
{
if($array[$i]>$key)
{
$array_r[]=$array[$i];
}
else
{
$array_l[]=$array[$i];
}
}
$array_r=quicksort($array_r);
$array_l=quicksort($array_l);
$array=array_merge($array_l,array($key),$array_r);
return$array;
}
print_r(quicksort($array));
echo'<hr>';
functioninsertsort($array)
{
$n=count($array);
for($i=1;$i<$n;$i++)//[0,i-1][i,n]
{
$j=$i-1;
$temp=$array[$i];
while($array[$j]>$temp)
{
$array[$j+1]=$array[$j];
$array[$j]=$temp;
$j--;
}
}
return$array;
}
print_r(insertsort($array));
?>
=======================================
<?php
/*
【插入排序(一维数组)】
【基本思想】:每次将一个待排序的数据元素,插入到前面已经排好序的数列中的适当位置,使数列依然有序;直到待排序数据元素全部插入完为止。
【示例】:
[初始关键字][49]38659776132749
J=2(38)[3849]659776132749
J=3(65)[384965]9776132749
J=4(97)[38496597]76132749
J=5(76)[3849657697]132749
J=6(13)[133849657697]2749
J=7(27)[13273849657697]49
J=8(49)[1327384949657697]
*/
functioninsert_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;
}
/*
【选择排序(一维数组)】
【基本思想】:每一趟从待排序的数据元素中选出最小(或最大)的一个元素,顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。
【示例】:
[初始关键字][4938659776132749]
第一趟排序后13[38659776492749]
第二趟排序后1327[659776493849]
第三趟排序后132738[9776496549]
第四趟排序后13273849[49976576]
第五趟排序后1327384949[979776]
第六趟排序后132738494976[7697]
第七趟排序后13273849497676[97]
最后排序结果1327384949767697
*/
functionselect_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;
}
/*
【冒泡排序(一维数组)】
【基本思想】:两两比较待排序数据元素的大小,发现两个数据元素的次序相反时即进行交换,直到没有反序的数据元素为止。
【排序过程】:设想被排序的数组R[1..N]垂直竖立,将每个数据元素看作有重量的气泡,根据轻气泡不能在重气泡之下的原则,
从下往上扫描数组R,凡扫描到违反本原则的轻气泡,就使其向上"漂浮",如此反复进行,直至最后任何两个气泡都是轻者在上,重者在下为止。
【示例】:
4913131313131313
3849272727272727
6538493838383838
9765384949494949
7697654949494949
1376976565656565
2727769776767676
4949497697979797
*/
functionbubble_sort($array){
$count=count($array);
if($count<=0)returnfalse;
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;
}
/*
【快速排序(一维数组)】
【基本思想】:在当前无序区R[1..H]中任取一个数据元素作为比较的"基准"(不妨记为X),
用此基准将当前无序区划分为左右两个较小的无序区:R[1..I-1]和R[I1..H],且左边的无序子区中数据元素均小于等于基准元素,
右边的无序子区中数据元素均大于等于基准元素,而基准X则位于最终排序的位置上,即R[1..I-1]≤X.Key≤R[I1..H](1≤I≤H),
当R[1..I-1]和R[I1..H]均非空时,分别对它们进行上述的划分过程,直至所有无序子区中的数据元素均已排序为止。
【示例】:
初始关键字[4938659776132749]
第一次交换后[2738659776134949]
第二次交换后[2738499776136549]
J向左扫描,位置不变,第三次交换后[2738139776496549]
I向右扫描,位置不变,第四次交换后[2738134976976549]
J向左扫描[2738134976976549]
(一次划分过程)
初始关键字[4938659776132749]
一趟排序之后[273813]49[76976549]
二趟排序之后[13]27[38]49[4965]76[97]
三趟排序之后1327384949[65]7697
最后的排序结果1327384949657697
各趟排序之后的状态
*/
functionquick_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);
returnarray_merge($left_arr,array($key),$right_arr);
}
/*打印数组全部内容*/
functiondisplay_arr($array){
$len=count($array);
for($i=0;$i<$len;$i++){
echo$array[$i].'';
}
echo'<br/>';
}
/*
几种排序算法的比较和选择
1.选取排序方法需要考虑的因素:
(1)待排序的元素数目n;
(2)元素本身信息量的大小;
(3)关键字的结构及其分布情况;
(4)语言工具的条件,辅助空间的大小等。
2.小结:
(1)若n较小(n<=50),则可以采用直接插入排序或直接选择排序。由于直接插入排序所需的记录移动操作较直接选择排序多,因而当记录本身信息量较大时,用直接选择排序较好。
(2)若文件的初始状态已按关键字基本有序,则选用直接插入或冒泡排序为宜。
(3)若n较大,则应采用时间复杂度为O(nlog2n)的排序方法:快速排序、堆排序或归并排序。快速排序是目前基于比较的内部排序法中被认为是最好的方法。
(4)在基于比较排序方法中,每次比较两个关键字的大小之后,仅仅出现两种可能的转移,因此可以用一棵二叉树来描述比较判定过程,由此可以证明:当文件的n个关键字随机分布时,任何借助于"比较"的排序算法,至少需要O(nlog2n)的时间。
(5)当记录本身信息量较大时,为避免耗费大量时间移动记录,可以用链表作为存储结构。
*/
/*排序测试*/
$a=array('12','4','16','8','13','20','5','32');
echo'Theresultofinsertsort:';
$insert_a=insert_sort($a);
display_arr($insert_a);
echo'Theresultofselectsort:';
$select_a=select_sort($a);
display_arr($select_a);
echo'Theresultofbubblesort:';
$bubble_a=bubble_sort($a);
display_arr($bubble_a);
echo'Theresultofbubblesort:';
$quick_a=quick_sort($a);
display_arr($quick_a);
?>
/**
*排列组合
*采用二进制方法进行组合的选择,如表示5选3时,只需有3位为1就可以了,所以可得到的组合是0110111100001111001101110等10种组合
*
*@param需要排列的数组$arr
*@param最小个数$min_size
*@return满足条件的新数组组合
*/
functionpl($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);
//递归算法
//阶乘
functionf($n){
if($n==1||$n==0){
return1;
}else{
return$n*f($n-1);
}
}
echof(5);
//遍历目录
functioniteral($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'));
更多关于PHP相关内容感兴趣的读者可查看本站专题:《PHP数据结构与算法教程》、《php程序设计算法总结》、《php加密方法总结》、《PHP编码与转码操作技巧汇总》、《php面向对象程序设计入门教程》、《PHP数学运算技巧总结》、《PHP数组(Array)操作技巧大全》、《php字符串(string)用法总结》、《php正则表达式用法总结》、及《php常见数据库操作技巧汇总》
希望本文所述对大家PHP程序设计有所帮助。