二分查找(时间O(log2n),空间O(1))
function binarySearch($arr, $val){
$low = 0;
$high = count($arr);
while($low <= $high){
$mid = floor(($low+$high)/2);
if($arr[$mid] === $val){
return $mid;
}
if($arr[$mid] > $val){
$high = $mid-1;
}
if($arr[$mid] < $val){
$low = $mid+1;
}
}
return -1;
}
$arr = [1,2,3,4,5,6];
var_dump(binarySearch($arr, 5));
冒泡排序(时间O(n^2),空间O(1))
function bubbleSort($arr){
$change = true;
for($i=0; $i<count($arr) && $change;$i++){
$change = false;
for($j=0;$j<count($arr)-$i-1;$j++){
if($arr[$j] > $arr[$j+1]){
$tmp = $arr[$j];
$arr[$j] = $arr[$j+1];
$arr[$j+1] = $tmp;
$change = true;
}
}
}
return $arr;
}
插入排序(时间O(n^2)空间O(1),插入排序的升级-希尔排序,时间O(nlog2n),空间O(1))
//与抓牌类似,左边是排好序的,拿右手的到左手进行排序
function insertSort($arr){
for($i = 1;$i < count($arr); $i++){
$flag = $arr[$i];
$j = $i-1;
while($j>=0 && $arr[$j] > $flag){
$arr[$j+1] = $arr[$j];
$j--;
}
$arr[$j+1] = $flag;
}
return $arr;
}
选择排序(O(n^2))
<?php
//每一趟,从右边选取最小值和标志位交换
function selectionSort($arr){
$temp= 0;
$flag= 0;
for($i=0; $i<count($arr); $i++){
$temp = $arr[$i];
$flag = $i;
for($j=$i+1; $j<count($arr); $j++){
if($arr[$j] < $temp){
$temp = $arr[$j];
$flag = $j;
}
}
if($i != $flag){
$temp = $arr[$i];
$arr[$i] = $arr[$flag];
$arr[$flag] = $temp;
}
}
return $arr;
}
快速排序(空间O(nlog2n),空间(log2n),冒泡排序的优化)
平均性能最好,但是初始序列有序或者基本有序时,会退化成冒泡排序。
<?php
//快速排序一趟
function quickSort(&$arr, $low, $high){
$flag = $arr[$low];
while($low < $high){
while($low < $high && $arr[$high] > $flag){
$high--;
}
$arr[$low] = $arr[$high];
while($low < $high && $arr[$low] <= $flag){
$low++;
}
$arr[$high] = $arr[$low];
}
$arr[$low] = $flag;
return $low;
}
//快速排序主函数
function recursionQuickSort(&$arr, $low, $high){
if($low < $high){
$boundary = quickSort($arr, $low, $high);
recursionQuickSort($arr, $low, $boundary);
recursionQuickSort($arr, $boundary+1, $high);
}
}
$arr = [6, 3, 1, 9];
recursionQuickSort($arr, 0, count($arr)-1);
var_dump($arr);
归并排序(时间O(nlog2n),空间O(n))
缺点是它需要存储器有另一个大小等于数据项数目的数组。如果初始数组几乎占满整个存储器,那么归并排序将不能工作,但是如果有足够的空间,归并排序会是一个很好的选择。
<?php
//归并排序
function mergeSort(&$array){
if(count($array) < 2){
return ;
}
$halfway = floor(count($array)/2);
$array1 = array_slice($array, 0, $halfway);
$array2 = array_slice($array, $halfway);
mergeSort($array1);
mergeSort($array2);
//如果array1整个大于或小于array2
if(end($array1) < $array2[0]){
$array = array_merge($array1, $array2);
}
if(end($array2) < $array1[0]){
$array = array_merge($array2, $array1);
}
//合并array1、array2到array
$array = [];
$l1 = count($array1);
$l2 = count($array2);
$i = $j = 0;
while($i<$l1 && $j < $l2){
if($array1[$i] < $array2[$j]){
$array[] = $array1[$i++];
}else{
$array[] = $array2[$j++];
}
}
while($j < $l2){
$array[] = $array2[$j++];
}
while($i < $l1){
$array[] = $array1[$i++];
}
return ;
}
$array = [3,2,4,1,5];
mergeSort($array);
var_dump($array);
无限分类生成树形结构
<?php
//递归实现
function genTree($items, $pid){
$tree = [];
foreach($items as $item){
if($item['pid'] == $pid){
$item['son'] = genTree($items, $item['id']);
if(!$item['son']){
unset($item['son']);
}
$tree[] = $item;
}
}
return $tree;
}
//非递归实现,循环中用引用变量
function genTree5($items){
foreach($items as $item){
$items[$item['pid']]['son'][$item['id']] = &$items[$item['id']];
}
return $items[0]['son'] ? $items[0]['son'] : [];
}
function genTree9($items){
$tree = [];
foreach($items as &$item){
if(isset($items[$item['pid']]))
$items[$item['pid']]['son'][] = &$items[$item['id']];
else
$tree[] = &$items[$item['id']];
}
return $tree;
}
$items = array(
1 => array('id' => 1, 'pid' => 0, 'name' => '江西省'),
2 => array('id' => 2, 'pid' => 0, 'name' => '黑龙江省'),
3 => array('id' => 3, 'pid' => 1, 'name' => '南昌市'),
4 => array('id' => 4, 'pid' => 2, 'name' => '哈尔滨市'),
5 => array('id' => 5, 'pid' => 2, 'name' => '鸡西市'),
6 => array('id' => 6, 'pid' => 4, 'name' => '香坊区'),
7 => array('id' => 7, 'pid' => 4, 'name' => '南岗区'),
8 => array('id' => 8, 'pid' => 6, 'name' => '和兴路'),
9 => array('id' => 9, 'pid' => 7, 'name' => '西大直街'),
10 => array('id' => 10, 'pid' => 8, 'name' => '东北林业大学'),
11 => array('id' => 11, 'pid' => 9, 'name' => '哈尔滨工业大学'),
12 => array('id' => 12, 'pid' => 8, 'name' => '哈尔滨师范大学'),
13 => array('id' => 13, 'pid' => 1, 'name' => '赣州市'),
14 => array('id' => 14, 'pid' => 13, 'name' => '赣县'),
15 => array('id' => 15, 'pid' => 13, 'name' => '于都县'),
16 => array('id' => 16, 'pid' => 14, 'name' => '茅店镇'),
17 => array('id' => 17, 'pid' => 14, 'name' => '大田乡'),
18 => array('id' => 18, 'pid' => 16, 'name' => '义源村'),
19 => array('id' => 19, 'pid' => 16, 'name' => '上坝村'),
);
echo "<pre>";
print_r(genTree($items,0));
?>
遍历下目录文件
<?php
//递归方法遍历
function scanFiles1($path){
$files = [];
if($handle = opendir($path)){
while(false !== ($afile = readdir($handle))){
if($afile == '.' || $afile == '..') continue;
$apath = $path . DIRECTORY_SEPARATOR . $afile;
if(is_dir($apath)){
$files[$afile] = call_user_func([$this, 'scanFiles1'], $apath);
}else{
$files[] = $afile;
}
}
}
return $files;
}
function scanFiles2($path){
$files = [];
if($list = scandir($path)){
foreach($list as $afile){
if($afile == '.' || $afile == '..') continue;
$apath = $path . DIRECTORY_SEPARATOR . $afile;
if(is_dir($apath)){
$files[$afile] = call_user_func([$this, 'scanFiles2'], $apath);
}else{
$files[] = $afile;
}
}
}
return $files;
}
获取两个数组中的相同元素(值与类型都相同)
function getSameElement($arr1, $arr2){
$arr = [];
foreach($arr1 as $v){
if(in_array($v, $arr2, true) && !in_array($v, $arr, true)){
$arr[] = $v;
}
}
return $arr;
}