PHP 零基础入门笔记(15):算法 algorithm
2023-09-14 09:07:18 时间
算法 algorithm
-
排序算法
- 冒泡排序 Bubble Sort
- 选择排序 Selection Sort
- 插入排序 Insert Sort
- 快速排序 Quick Sort
- 归并排序 Merge Sort
-
查找算法
- 顺序查找
- 二分查找
冒泡排序
两两比较,顺序错误就交换,直到该数列已经完成排序
算法思路
比较相邻的元素,顺序不对就交换
代码实现
<?php
// 将数组由小到大排序
$arr = [3, 4, 2, 8, 9, 1, 6];
// 每次遍历将最大值放在最右边
for($i = 0, $len = count($arr); $i < $len; $i++){
// 将大值的放在右边
for($j = 0, $len = count($arr); $j < $len - 1 - $i; $j++){
// 如果左边的值比右边的大,就交换位置
if($arr[$j] > $arr[$j + 1]){
$temp = $arr[$j];
$arr[$j] = $arr[$j + 1];
$arr[$j + 1] = $temp;
}
}
}
echo json_encode($arr);
// [1,2,3,4,6,8,9]
选择排序
每次从待排的数据中选择最小或最大的一个元素,放在起始位置,直到全部待排序的元素排完
<?php
// 将数组由小到大排序
$arr = [3, 4, 2, 8, 9, 1, 6];
// 1、需要选择的次数,每次只能选择一个最大或者最小值
for($i = 0, $len = count($arr); $i < $len; $i++){
// 2、假设第一个值就是最小值
$min = $i;
// 3、将最小值和其他剩余值一一比较
for($j = 1 + $i, $len = count($arr); $j < $len; $j++){
// 4、找到最小值
if($arr[$min] > $arr[$j]){
$min = $j;
}
}
// 5、当前值与最小值交换位置
if($min != $i){
$temp = $arr[$i];
$arr[$i] = $arr[$min];
$arr[$min] = $temp;
}
}
echo json_encode($arr);
// [1,2,3,4,6,8,9]
插入排序
将一个数据插入到已排序数据中
<?php
// 将数组由小到大排序
$arr = [3, 4, 2, 8, 9, 1, 6];
// 1、循环次数,插入次数 length - 1,第一个数已经是有序的了
for($i = 1, $len = count($arr); $i < $len; $i++){
// 待插入数据
$temp = $arr[$i];
// 2、前面的序列是已排序区域
for($j = $i - 1; $j >= 0; $j--){
// 3、将该值插入到合适的位置
if($arr[$j] > $temp){
// 有序数组后移一位
$arr[$j + 1] = $arr[$j];
$arr[$j] = $temp;
} else{
// 该值最大,位置正确
break;
}
}
}
echo json_encode($arr);
// [1,2,3,4,6,8,9]
优化版本, 减少交换次数
<?php
// 将数组由小到大排序
$arr = [3, 4, 2, 8, 9, 1, 6];
// 1、循环次数,插入次数 length - 1,第一个数已经是有序的了
for($i = 1, $len = count($arr); $i < $len; $i++){
// 待插入数据
$temp = $arr[$i];
// 记录插入位置
$insert_index = -1;
// 2、前面的序列是已排序区域
for($j = $i - 1; $j >= 0; $j--){
// 3、将该值插入到合适的位置
if($arr[$j] > $temp){
// 有序数组后移一位
$arr[$j + 1] = $arr[$j];
// $arr[$j] = $temp;
$insert_index = $j;
} else{
// 该值最大,位置正确
break;
}
}
// 如果位置有变动,交换数据
if($insert_index > -1){
$arr[$insert_index] = $temp;
}
}
echo json_encode($arr);
// [1,2,3,4,6,8,9]
快速排序
不稳定排序
冒泡排序的改进,通过一趟排序将要排序的数据分割为独立的两部分,其中一部分的数据都比另外一部分所有数据都要小,然后重复此过程
排序步骤:
- 从数组中选出一个元素(通常是第一个),作为参照
- 定义两个数组,将目标数组中剩余元素与参照元素挨个比较,小的放到一组,大的放到另一组
- 第二步执行完后,前后数组顺序不确定,但是确定了自己的位置
- 将得到的小数组按照第1步第3步,重复操作(子问题)
- 回溯最小数组(第一个元素)
<?php
// 将数组由小到大排序
$arr = [3, 4, 2, 8, 9, 1, 6];
/**
* 快速排序
*/
function quick_sort($arr){
// 递归出口
$len = count($arr);
if($len <= 1){
return $arr;
}
// 定义两个数组,分别存小数和大数
$left = [];
$right = [];
for($i = 1; $i < $len; $i++){
// 比较:小的放左边,大的放右边
if($arr[$i] < $arr[0]){
$left[] = $arr[$i];
} else {
$right[] = $arr[$i];
}
}
// 递归点:将两个数组继续排序
$left = quick_sort($left);
$right = quick_sort($right);
// 和并数组返回
return array_merge($left, [$arr[0]], $right);
}
echo json_encode(quick_sort($arr));
// [1,2,3,4,6,8,9]
归并排序
分治算法
二路归并
<?php
// 将数组由小到大排序
$arr1 = [2, 3, 4, 8];
$arr2 = [1, 6, 9];
// 定义归并空间
$arr3 = [];
while(count($arr1) && count($arr2)){
// 每次取出一个最小值
$arr3[] = $arr1[0] < $arr2[0] ? array_shift($arr1): array_shift($arr2);
}
// 合并结果
$ret = array_merge($arr3, $arr1, $arr2);
echo json_encode($ret);
// [1,2,3,4,6,8,9]
<?php
// 将数组由小到大排序
$arr = [3, 4, 2, 8, 9, 1, 6];
function merge_sort($arr){
// 递归出口
$len = count($arr);
if($len <= 1){
return $arr;
}
// 拆分为两个数组
$middle_index = floor($len/2);
$left = array_slice($arr, 0, $middle_index);
$right = array_slice($arr, $middle_index);
// 递归点
$left = merge_sort($left);
$right = merge_sort($right);
// 定义归并空间
$merge_array = [];
while(count($left) && count($right)){
// 每次取出一个最小值
$merge_array[] = $left[0] < $right[0] ? array_shift($left): array_shift($right);
}
// 合并结果
return array_merge($merge_array, $left, $right);
}
// 合并结果
$ret = merge_sort($arr);
echo json_encode($ret);
// [1,2,3,4,6,8,9]
顺序查找
按照列表顺序,依次查找
<?php
/**
* 顺序查找,逐项匹配
*/
function order_find($arr, $value){
for($i = 0, $len = count($arr); $i < $len; $i++){
// 判断
if($arr[$i] == $value){
return $i;
}
}
return -1;
}
$arr = [3, 4, 2, 8, 9, 1, 6];
$ret = order_find($arr, 1);
var_dump($ret);
// int(5)
二分查找
要求元素组有序,先与中间节点比较,分成两个子表,确定继续在哪个子表查找,递归进行
折半查找
<?php
/**
* 二分查找,从中间的值开始比较
*/
function binary_find($arr, $value){
// 边界条件
$left = 0;
$right = count($arr);
// 循环匹配
while($left <= $right){
// 每次循环获取中间值
$middle = floor(($left + $right) / 2);
if($value > $arr[$middle]){
$left = $middle + 1;
} else if($value < $arr[$middle]){
$right = $middle - 1;
} else{
return $middle;
}
}
return -1;
}
// 有序数组
$arr = [1, 2, 4, 8, 9, 13, 16];
$ret = binary_find($arr, 9);
var_dump($ret);
// float(4)
相关文章
- PHP常见面试题_php面试常问面试题
- php安装ssh2拓展,支持php7
- php 结合lua和redis保护API(令牌桶算法)
- 笛卡尔积 php,PHP笛卡尔积实现算法示例
- PHP DFA算法实现敏感词过滤包 php-dfa-sensitive
- 数据PHP简单操作实现MySQL数据输出(php输出mysql)
- PHP 抛出异常嵌套用法详解编程语言
- php微信卡券logo上传方法详解编程语言
- PHP实现Redis的访问控制(php访问redis)
- 使用PHP操作Redis:简单灵活的方法(php如何使用redis)
- PHP操纵Redis实例:快速高效存储数据(php操作redis实例)
- PHP与MSSQL:高效开发数据驱动应用程序(php与mssql)
- PHP检测MySQL性能的方法(php检测mysql)
- 使用PHP在Linux系统中运行命令(php运行linux命令)
- 如何使用Linux控制PHP进程?(linuxphp进程)
- PHP连接MSSQL数据库的方法和步骤(php如何连接mssql)
- PHP与MySQL完美结合:数据库操作常用语句及优化技巧(php使用mysql)
- PHP环境搭建:从编译MSSQL说起(php 编译mssql)
- PHP如何连接MSSQL服务器(php怎么连mssql)
- PHP与MSSQL的良好结合,发挥强大的功能(php和mssql)
- PHP连接MSSQL数据库发生错误解决方法(php mssql 错误)
- Php与Mssql数据库的结合:强大联合力量(php mssql数据库)
- 使用 PHP 连接 MSSQL 程序的源码探索(phpmssql源码)
- PHP+DBM的同学录程序(1)
- php数据结构与算法(PHP描述)快速排序quicksort
- PHP正则表达式之正则处理函数小结(preg_match,preg_match_all,preg_replace,preg_split)
- PHP输出XML到页面的3种方法详解
- php读取csv文件后,uft8bom导致在页面上显示出现问题的解决方法
- php模板原理讲解
- PHP数字字符串左侧补0、字符串填充和自动补齐的几种方法
- php写的AES加密解密类分享
- php实现微信公众平台账号自定义菜单类
- php中的观察者模式简单实例
- PHP中echo和print的区别