php常用算法实现
#冒泡算法
/**
* 冒泡排序是最基础的排序算法,他设计的逻辑也是我们最容易想到的,通过两层循环遍历。
* 第一层遍历是根据这个数组的元素个数,因为要保证每次遍历后数组中最大的值跑到底部
* 第二层遍历是真正的比较两个数值大小,把大的数值往后靠
* 最后有个优化的点是通过一个标识如swag变量来记录第二层遍历是否有交换过数据
* 因为如果没有交换数据了,说明就已经排好序的了,直接退出。
*/
<?php
function bubble_sort($array)
{
$len = count($array);
$swag = false;
for ($j = 0; $j < $len; $i++) {
for ($j = 1; $j < $len - $i; $j++) {
if ($array[$j-1] > $array[$j]) {
[$array[$j-1], $array[$j]] = [$array[$j], $array[$j-1]];
$swag = true;
}
}
if ($swag === false) { //判断上次循环是否有交换,没有交互说明已经有序,就不用循环了
break;
}
}
return $array;
}
#归并排序
/**
* 归并排序用到了分治思想,将一个大问题,拆分成各个小的子问题,最后将子问题得到的结果再合并成最终的结果
* 分治思想的实现是通过递归算法,递归算法刚好符合分治思想
* 重点是最后的合并两个有序数组merge函数,不过这个也不难
* 时间复杂度是O(nlogn)
* 空间复杂度是O(n)
* 非原地排序,稳定排序
*/
<?php
function merge_sort($a)
{
$n = count($arr);
return merge_sort_c($a, 0, $n-1);
}
function merge_sort_c($a, $left, $right)
{
if ($left >= $right) {
return [$a[$right]]; //递归退出条件,获取return [$a[$left]];
}
$mid = floor(($left + $right) / 2);
$left = merge_sort_c($a, $left, $mid);
$right = merge_sort_c($a, $mid+1, $right);
return merge($left, $right);
}
function merge($left, $right)
{
$i = 0; $j = 0;
$tmp = [];
while (isset($left[$i]) && isset($right[$j])) {
If ($left[$i] < $right[$j]) {
$tmp[] = $left[$i];
$i++;
} else {
$tmp[] = $right[$j];
$j++;
}
}
while (isset($left[$i]) {
$tmp[] = $left[$i];
$i++;
}
while (isset($right[$j])) {
$tmp[] = $right[$j];
$j++;
}
return $tmp;
}
#快速排序
<?php
/**
* 快速排序是时间复杂度也是O(nlogn)
* 但是空间复杂度O(1)
* 所以相对来说大家都喜欢用快速排序,而且利用快速排序可以很快就能计算出第K大/小的值是多少
* 快速排序相对于归并排序的区别点是:快速排序是选择一个值pviot,然后将数组分成三部分, < pviot, pviot, > pviot。
* 重点是这个pviot这个值的函数partition(),这个函数实现了原地排序,空间复杂度是O(1)。
* 利用两个指针i,j一开始同时指向第一个,在遍历过程中,如果遇到比pviot值小的,就将i,j所指的数据交换位置,如果比pviot大,i不动,j往后移动一位
* 最后交换pviot与i所指的数据位置,这样就能将数组划分三部分了,然后对左右进行相同的递归操作。
*/
function quick_sort($a)
{
quick_sort_c($a, 0, $n—1);
}
function quick_sort_c(&$a, $left, $right)
{
if ($left >= $right) {
return;
}
$partition = partition($a, $left, $right);
quick_sort_c($a, $left, $partition-1);
quick_sort_c($a, $partition+1, $right);
}
function partition(&$a, $left, $right)
{
$p = $a[$right];
$j = $left;
for ($i = $left; $i < $right; $i++) {
If ($a[$i] < $p) {
[$a[j], $a[$i]] = [$a[$i], $a[$j]];
$j++;
}
}
[$a[$j], $a[$right]] = [$a[$right], $a[$j]];
return $j;
}
#二分查找
<?php
function binary_search($a, $v)
{
$n = count($a);
return binary_search_c($a, 0, $n - 1, $v);
}
//递归实现
function binary_search_c($a, $low, $hight, $v)
{
If ($low > $hight) {
return false;
}
$mid = floor(($low + $hight) / 2);
if ($a[$mid] > $v) {
return binary_search_c($a, $mid + 1, $hight, $v);
} else if ($a[$mid] < $v) {
return binary_search_c($a, $low, $mid - 1, $v);
} else {
return $mid;
}
}
//非递归实现
function binary_search_u($a, $v)
{
$low = 0;
$hight = count($a);
If ($hight == 0) {
return -1;
}
while ($low <= $hight) {
$mid = floor(($low + $hight) / 2);
If ($a[$mid] > $v) {
$hight = $mid - 1;
} else if ($a[$mid] < $v) {
$low = $mid + 1;
} else {
return $mid;
}
}
return -1;
}
未完待续。。。