PHP中的一些基本算法和数据结构(一)

3 篇文章 0 订阅
1 篇文章 0 订阅

1.0:冒泡排序

基本思想:

对需要排序的数组从后往前(逆序)进行多遍的扫描,当发现相邻的两个数值的次序与排序要求的规则不一致时,就将这两个数值进行交换。这样比较小(大)的数值就将逐渐从后面向前面移动。

<?php

function mysort($arr)

{

for($i = 0; $i < count($arr); $i++)

{

$isSort = false;

for ($j=0; $j< count($arr) - $i - 1; $j++)

{

if($arr[$j] < $arr[$j+1])

{

$isSort = true;

$temp = $arr[$j];

$arr[$j] = $arr[$j+1];

$arr[$j+1] = $temp ;

}

}

if($isSort)

{

break;

}

}

return $arr;

}

$arr = array(3,1,2);

var_dump(mysort($arr));

?>

1.1:快速排序

基本思想:

在数组中挑出一个元素(多为第一个)作为标尺,扫描一遍数组将比标尺小的元素排在标尺之前,将所有比标尺大的元素排在标尺之后,通过递归将各子序列分别划分为更小的序列直到所有的序列顺序一致。

<?php

//快速排序

function quick_sort($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);

}

$arr = array(3,1,2);

var_dump(quick_sort($arr));

?>

 

1.2:二分查找

基本思想:

假设数据是按升序排序的,对于给定值x,从序列的中间位置开始比较,如果当前位置值等于x,则查找成功;若x小于当前位置值,则在数列的前半段中查找;若x大于当前位置值则在数列的后半段中继续查找,直到找到为止。(数据量大的时候使用)

<?php

//二分查找

function bin_search($arr,$low,$high,$k)

{

if($low <= $high)

{

$mid = intval(($low + $high)/2);

if($arr[$mid] == $k)

{

return $mid;

}

else if($k < $arr[$mid])

{

return bin_search($arr,$low,$mid-1,$k);

}

else

{

return bin_search($arr,$mid+1,$high,$k);

}

}

return -1;

}

$arr = array(1,2,3,4,5,6,7,8,9,10);

print(bin_search($arr,0,9,3));

?>

 

1.3:顺序查找

基本思想:

从数组的第一个元素开始一个一个向下查找,如果有和目标一致的元素,查找成功;如果到最后一个元素仍没有目标元素,则查找失败。

<?php

//顺序查找

function seq_search($arr,$n,$k)

{

$array[$n] = $k;

for($i = 0;$i < $n; $i++)

{

if($arr[$i] == $k)

{

break;

}

}

if($i < $n)

{

return $i;

}

else

{

return -1;

}

}

?>

 

1.4:遍历文件夹

<?php

function my_scandir($dir)

{

$files = array();

if($handle = opendir($dir))

{

while (($file = readdir($handle))!== false)

{

if($file != '..' && $file != '.')

{

if(is_dir($dir."/".$file))

{

$files[$file]=my_scandir($dir."/".$file);

}

else

{

$files[] = $file;

}

}

}

closedir($handle);

return $files;

}

}

var_dump(my_scandir('../'));

?>

 

1.5:写一个函数,尽可能高效的从一个标准url中取出文件的扩展名

<?php

function getExt($url)

{

$arr = parse_url($url);//parse_url解析一个 URL 并返回一个关联数组,包含在 URL 中出现的各种组成部分

//'scheme' => string 'http' (length=4)

//'host' => string 'www.sina.com.cn' (length=15)

//'path' => string '/abc/de/fg.php' (length=14)

//'query' => string 'id=1' (length=4)

$file = basename($arr['path']);// basename函数返回路径中的文件名部分

$ext = explode('.', $file);

return $ext[count($ext)-1];

}

print(getExt('http://www.sina.com.cn/abc/de/fg.html.php?id=1'));

?>

.用多种方式获取url的后缀名?$url="http://localhost/user/order.php?id=3";

//第一种:pathinfo()函数

$url1 = 'http://www.baidu.com/index.php?id=1234&a=qwer';

$array = pathinfo($url1);

$extension = $array['extension'];

$position = strpos($extension, '?');

$result = $position === false ? $extension : substr($extension, 0, $position);

echo $result."<br/>";

 

//第二种:parse_url()函数

$url2 = 'http://www.baidu.com/index.php?id=1234&a=qwer';

$array = parse_url($url2);

$path = $array['path'];

$result2 = substr($path, strpos($path, '.'));

echo $result2;

 

1.6:实现中文字符串截取无乱码的方法

可使用mb_substr,但是需要确保在php.ini中加载了php_mbstring.dll,即确保“extension=php_mbstring.dll”这一行存在并且没有被注释掉,否则会出现未定义函 数的问题。

 

1.7:数据结构和算法

使对象可以像数组一样进行foreach循环,要求属性必须是私有。(Iterator模式的PHP5实现,写一类实现Iterator接口)(腾讯)

<?php

class Test implements Iterator{

private $item = array('id'=>1,'name'=>'php');

public function rewind(){

reset($this->item);

}

public function current(){

return current($this->item);

}

public function key(){

return key($this->item);

}

public function next(){

return next($this->item);

}

public function valid(){

return($this->current()!==false);

}

}

//测试

$t=new Test;

foreach($t as $k=>$v){

echo$k,'--->',$v,'<br/>';

}

?>

 

1.8:用PHP 实现一个双向队列(腾讯)

<?php

class Deque{

private $queue=array();

public function addFirst($item){

return array_unshift($this->queue,$item);

}

public function addLast($item){

return array_push($this->queue,$item);

}

public function removeFirst(){

return array_shift($this->queue);

}

public function removeLast(){

return array_pop($this->queue);

}

}

?>

 

实战开始:::

1.10:冒泡排序对数组$arr=array(10,2,36,14,10,25,23,85,99,45);进行排序

<?php

// 冒泡排序

function bubble_sort(&$arr){

for ($i=0,$len=count($arr); $i < $len; $i++) {

for ($j=1; $j < $len-$i; $j++) {

if ($arr[$j-1] > $arr[$j]) {

$temp = $arr[$j-1];

$arr[$j-1] = $arr[$j];

$arr[$j] = $temp;

}

}

}

}

// 测试

$arr = array(10,2,36,14,10,25,23,85,99,45);

bubble_sort($arr);

print_r($arr);

?>

 

1.11:写一种算法,并切进行优化(新浪)

<?php

//快速排序

function partition(&$arr,$low,$high){

$pivotkey = $arr[$low];

while($low<$high){

while($low < $high && $arr[$high] >= $pivotkey){

$high--;

}

$temp = $arr[$low];

$arr[$low] = $arr[$high];

$arr[$high] = $temp;

while($low < $high && $arr[$low] <= $pivotkey){

$low++;

}

$temp=$arr[$low];

$arr[$low]=$arr[$high];

$arr[$high]=$temp;

}

return$low;

}

function quick_sort(&$arr,$low,$high){

if($low < $high){

$pivot = partition($arr,$low,$high);

quick_sort($arr,$low,$pivot-1);

quick_sort($arr,$pivot+1,$high);

}

}

?>

 

1.12:面试题猴子算法:

一群猴子排成一圈,按1,2,...,n依次编号。然后从第1只开始数,数到第m只,把它踢出圈,从它后面再开始数,再数到第m只,在把它踢出去...,如此不停的进行下去,直到最后只剩下一只猴子为止,那只猴子就叫做大王。要求编程模拟此过程,输入m、n,输出最后那个大王的编号。(新浪)(小米)

<?php

// 方案一,使用php来模拟这个过程

function king($n,$m){

$mokey = range(1, $n);

$i = 0;

while (count($mokey) >1) {

$i += 1;

$head = array_shift($mokey);//一个个出列最前面的猴子

if ($i % $m !=0) {

#如果不是m的倍数,则把猴子返回尾部,否则就抛掉,也就是出列

array_push($mokey,$head);

}

// 剩下的最后一个就是大王了

return $mokey[0];

}

}

// 测试

echo king(10,7);

// 方案二,使用数学方法解决

function josephus($n,$m){

$r = 0;

for ($i=2; $i <= $m ; $i++) {

$r = ($r + $m) % $i;

}

return $r+1;

}

// 测试

print_r(josephus(10,7));

?>

 

1.13:二维数组排序算法函数,能够具有通用性,可以调用php内置函数

<?php

function array_sort($arr,$keys,$order=0){

    if(!is_array($arr)){

        return false;

    }

//根据指定的字段和内层数组的下标组成新的一维数组

    $keysvalue=array();

    foreach($arr as $key => $val){

        $keysvalue[$key] = $val[$keys];

    }

print_r($keysvalue);

//对数组按照指定字段排序并保持索引关系

    if($order == 0){

        asort($keysvalue);

    }else{

        arsort($keysvalue);

    }

print_r($keysvalue);

   

    $new_array=array();

//按照排好序的下标,重新组合原二维数组

    foreach($keysvalue as $key => $val){

        $new_array[$key] = $arr[$key];

    }

    return $new_array;

}

    //测试

    $person=array(

        array('id'=>2,'name'=>'lhangsan','age'=>23),

        array('id'=>5,'name'=>'zisi','age'=>28),

        array('id'=>3,'name'=>'apple','age'=>17)

    );

    $result = array_sort($person,'name',0);

    print_r($result);

 

?>

 

1.14:顺序查找和二分查找(也叫做折半查找)算法,顺序查找必须考虑效率,对象可以是一个有序数组(小米)

<?php

/**

* 顺序查找

* @param array $arr 数组

* @param $k 要查找的元素

* @return mixed 成功返回数组下标,失败返回-1

*/

function seq_sch($arr,$k){

for ($i=0,$n = count($arr); $i < $n; $i++) {

if ($arr[$i] == $k) {

break;

}

}

if($i < $n){

return $i;

}else{

return -1;

}

}

/**

* 二分查找,要求数组已经排好顺序

* @param array $array 数组

* @param int $low 数组起始元素下标

* @param int $high 数组末尾元素下标

* @param $k 要查找的元素

* @return mixed 成功时返回数组下标,失败返回-1

*/

function bin_sch($array,$low,$high,$k){

if ($low <= $high) {

$mid = intval(($low + $high) / 2);

if ($array[$mid] == $k) {

return $mid;

} elseif ($k < $array[$mid]) {

return bin_sch($array,$low,$mid - 1,$k);

} else{

return bin_sch($array,$mid + 1,$high,$k);

}

}

return -1;

}

// 测试:顺序查找

$arr1 = array(9,15,34,76,25,5,47,55);

echo seq_sch($arr1,47);//结果为6

echo "<br />";

// 测试:二分查找

$arr2 = array(5,9,15,25,34,47,55,76);

echo bin_sch($arr2,0,7,47);//结果为5

?>

 

1.15:洗牌算法

<?php

$card_num = 54;//牌数

function wash_card($card_num){

$cards = $tmp = array();

for($i = 0;$i < $card_num;$i++){

$tmp[$i] = $i;

}

for($i = 0;$i < $card_num;$i++){

$index = rand(0,$card_num-$i-1);

$cards[$i] = $tmp[$index];

unset($tmp[$index]);

$tmp = array_values($tmp);

}

return $cards;

}

// 测试:

print_r(wash_card($card_num));

?>

 

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值