基础算法(枚举、递归、二分、归并、快速) php
?代码语言:php
?
什么是算法
数据元素之间的关系有逻辑关系和物理关系,对应的运算有基于逻辑结构的运算描述和基于存储结构的运算实现。
通常把基于存储结构的运算实现的步骤或过程称之为算法。
算法的五个重要的特性
有穷性:在有穷步之后结束,算法能够停机。
确定性:无二义性。
可行性:可通过基本原酸有限次执行来实现,也就是算法中每一个动作能够被机械地执行。
有输入。
有输出。
枚举:
枚举就是将所有的结果进行尝试计算。
优化的思路
循环的时候,根据 所需要的顺序,进行循环,将一些不需要的结果省去循环时间。
eg :
形如a^3= b^3 + c^3 + d^3的等式被称为完美立方等式。例如
123= 63 + 83 + 103 。编写一个程序,对任给的正整数N (N≤100),寻找所有的四元组(a, b, c, d),使得a3 = b3 + c3 + d3,其中a,b,c,d 大于1, 小于等于N,且b<=c<=d。
输入
一个正整数N (N≤100)。
输出
每行输出一个完美立方。输出格式为: Cube = a, Triple = (b,c,d)
其中a,b,c,d所在位置分别用实际求出四元组值代入。
解题思路:
a枚举的范围是[2,N]
b枚举的范围是[2,a-1]
c枚举的范围是[b,a-1]
b枚举的范围是[2,a-1]
c枚举的范围是[b,a-1]
b枚举的范围是[c,a-1]
定义 $a,$b,$c,$d
function meiju(){
$array = [];
for($a=2;$a<=$N;$a++){
for($b=2;$b<=$a-1;$b++){
for($c=$b;$c<=$a-1;$c++){
for($d=$c;$d<=$a-1;$d++){
if($a*$a*$a==$b*$b*$b+$c*$c*$c+$d*$d*$d){
$array[] = [$a,$b,$c,$d];
}
}
}
}
}
return $array;
}
递归
递归就是自己调用自己。
递归的作用 :
替代多重循环。
解决本来就是用递归形式定义的问题。
将问题分解为规模更小的子问题进行求解。
将 数组进行中间分开 每次查找是原来的1/2的数据量。
eg:
输入: nums = [-1,0,3,5,9,12], target = 9
输出: 4
解释: 9 出现在 nums 中并且下标为 4function search($nums, $target) {
if(!is_array($nums) && empty($nums)){
return -1;
}
$heid = count($nums)-1;//查找的最右边
$lowr = 0; //查找的最左边
while($lowr <= $heid){ // 查询区间
$middle = intval($lowr+($heid-$lowr)/2); // 找出中间值 $heid-$lowr防止数据太大,内存溢出
if($nums[$middle] > $target){
$heid = $middle - 1; //设置最右边
}else if($nums[$middle] < $target){
$lowr = $middle + 1; //设置最左边
}else{
return $middle;
}
}
return -1;
}
归并排序
使用了分治的思想 将一个数组进行分开,分别对两个数组进行排序,再将数组重组
输入 : [9,5,4,2,1,4,8,96,12,0,5,4,8,6,74]
输出 : 0,1,2,4,4,4,5,5,6,8,8,9,12,74,96function msort(&$arr,$low,$high){
if($low<$high){
$mid = floor(($low+$high)/2);
msort($arr, $low, $mid);
msort($arr,$mid+1,$high);
mergeArray($arr,$low,$mid,$high);
}
}
?
function mergeArray(&$arr,$low,$mid,$high){
$i = $low;
$j = $mid+1;
?
while($i<=$mid && $j<=$high){
if($arr[$i]<$arr[$j]){
$tmp[] = $arr[$i++];
}else{
$tmp[] = $arr[$j++];
}
}
?
while($i<=$mid){
$tmp[] = $arr[$i++];
}
while($j<=$high){
$tmp[] = $arr[$j++];
}
$len = count($tmp);
for($k=0;$k<$len;$k++){
$arr[$low+$k] = $tmp[$k];
}
}
快速排序
从数组中取出一个数作为基准数。
分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
再对左右区间重复第二步,直到各区间只有一个数。
输入 : [9,5,4,2,1,4,8,96,12,0,5,4,8,6,74]
输出 : 0,1,2,4,4,4,5,5,6,8,8,9,12,74,96function quick_sort($my_array)
{
//定义两个中间值
$loe = $gt = array();
if (count($my_array) < 2) {
return $my_array;
}
$pivot_key = key($my_array);
$pivot = array_shift($my_array);
foreach ($my_array as $val) {
if ($val <= $pivot) {
$loe[] = $val;
} elseif ($val > $pivot) {
$gt[] = $val;
}
}
return array_merge(quick_sort($loe), array($pivot_key => $pivot), quick_sort($gt));
}