用PHP实现经典的4种排序算法

news2024/12/23 3:58:44

文章目录

  • 一、前言
  • 二、4种排序算法
    • 2.1 快速排序
    • 2.2 插入排序
    • 2.3 选择排序
    • 2.4 冒泡排序
  • 总结


一、前言

排序算法是一种将一组无序的数据元素按照某个规则(大小、字母序等)排列成有序的序列的算法。常见的排序算法包括冒泡排序、选择排序、插入排序、快速排序、归并排序等。

在这里插入图片描述

1.冒泡排序:比较相邻元素的大小,如果前面比后面大,则交换两个元素。通过多轮扫描,最大的元素被交换到了最后一位。

2.选择排序:每次选取当前未排序部分中最小的元素,放到已排序部分的末尾。

3.插入排序:将未排序部分逐个插入到已排序部分中的正确位置,使得已排序部分一直有序。

4.快速排序:选择一个基准元素,根据比基准元素小的和比基准元素大的将序列分为两部分,对两部分递归地进行排序。

5.归并排序:将序列拆分成长度为一的子序列,然后将相邻的子序列合并,不断重复直到序列有序。

以上这些排序算法都有各自的优点和缺点,在实际应用中需要根据具体情况选择合适的算法。本文将对4种排序算法进行讲解。

二、4种排序算法

本文使用到的数据生成工具类代码如下:

<?php
class Generate {
    private $n = 0;

    public function __construct($n)
    {
        $this->n = $n;
    }

    public function randNumberArray()
    {
        $data = [];
        for ($i = 0; $i< $this->n; $i++) {
            $data[] = rand(1, 100);
        }
        return $data;
    }
}

2.1 快速排序

快速排序是一种常用的排序算法,它以递归的方式对待排序数据进行排序。快速排序的基本思路是将待排序数据序列划分成两个子序列,一个子序列中所有元素都比另一个子序列中的元素小(或大),再对这两个子序列递归进行快速排序,直到每个子序列只有一个元素为止

具体来说,快速排序要选择一个基准元素,把待排序数据按照这个基准元素进行划分。一般情况下,我们选择第一个元素作为基准元素(也可以随机选择),然后从序列的右端开始往左扫描,找到第一个比基准元素小的元素,并将其与基准元素交换;接着从序列的左端开始往右扫描,找到第一个比基准元素大的元素,并将其与基准元素交换。这样就完成了一次划分,基准元素也就排好了位置。然后对左右两个子序列递归进行快速排序即可。

快速排序的时间复杂度为O(nlogn),空间复杂度为O(logn)。但是快速排序也有缺点,当数据已经有序或近似有序时,快排效率会非常低,甚至退化到O(n^2)的时间复杂度。因此,实际应用中需要根据具体情况选择合适的排序算法。

<?php
include '../Generate.php';

/**
 * 思路分析:选择一个基准元素,通常选择第一个元素或者最后一个元素。通过一趟扫描,将待排序列分成两部分,一部分比基准元素小,一部分大于等于基准元素。
 * 此时基准元素在其排好序后的正确位置,然后再用同样的方法递归地排序划分的两部分。
 */
class QuickSort {

    public function run($data)
    {
        return $this->_quickSort($data);
    }

    // 将一个数组分成两部分,左边部分大于第一个元素,右边部分小于第一个元素,最后把第一个元素放在他们中间
    private function _quickSort($data)
    {
        if(count($data) <= 1) {
            return $data;
        }
        $left = $right = [];
        $targetValue = $data[0];
        $r = count($data);
        for ($i = 1; $i < $r; $i ++ ) {
            if($data[$i] < $targetValue) {
                $left[] = $data[$i];
            }else {
                $right[] = $data[$i];
            }
        }
        return array_merge($this->_quickSort($left), [$data[0]], $this->_quickSort($right));
    }
}

$res = (new QuickSort())->run((new Generate(100))->randNumberArray());
echo json_encode($res);

2.2 插入排序

插入排序是一种简单直观的排序算法,其核心思想是将待排序的元素插入到已排好序的序列中,通过不断地插入和比较,最终完成排序。具体实现流程如下:

  • 将第一个元素视为已排序序列,从第二个元素开始遍历;
  • 依次将每个元素插入到已排序序列中的正确位置,插入过程中需要比较大小并交换位置;
  • 重复步骤2,直到所有元素都插入到已排序序列中,排序完成。

插入排序的时间复杂度为O(n^2),空间复杂度为O(1),适用于小规模数据的排序。此外,插入排序还具有稳定性,即相等元素的相对位置不会改变。

在这里插入图片描述

include '../Generate.php';
class InsertSort {

    public function swap($i, $j, &$data) {
        $tmp = $data[$i];
        $data[$i] = $data[$j];
        $data[$j] = $tmp;
    }

    public function run($data)
    {
        $n = count($data);
        // i 依次从前往后取,时刻维护i前面的顺序是有序的,不是有序的变成有序的
        for ($i = 1; $i < $n; $i++) {
            // 用j 依次取i前面的数和i比较,当前面存在大于j位置的数,就发生交换行为
            for ($j = $i-1; $j >= 0; $j--) {
                if($data[$j] > $data[$i]) {
                    $this->swap($j, $i, $data);
                    $i --;
                } else {
                    // 前面数据本身是有序的,如果不存在交换,表示已经是有序,可直接退出
                    break;
                }
            }
        }
        return $data;
    }
}

$res = (new InsertSort())->run((new Generate(100))->randNumberArray());
echo json_encode($res);

2.3 选择排序

选择排序(Selection Sort)是一种简单直接的排序算法,它的基本思想是: 每趟从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完

具体实现过程如下:

  • 遍历数组,找到最小的元素,将其与第一个元素交换;
  • 从第二个元素开始遍历,找到剩余元素中最小的元素,将其与第二个元素交换;
  • 重复上述步骤,直到排序完成。

选择排序算法的时间复杂度为O(n^2),其中n为待排序元素的个数,需要进行的比较次数和交换次数都很多。虽然效率不如其他高级排序算法,但由于其简单直观,是初学者学习排序算法的良好入门知识点。

class SelectSort {

    public function swap($i, $j, &$data) {
        $tmp = $data[$i];
        $data[$i] = $data[$j];
        $data[$j] = $tmp;
    }

    public function run($data)
    {
        $n = count($data);
        for ($i = 0; $i < $n; $i++) {
            $min = $data[$i];
            $k = $i;
            for($j = $i + 1; $j < $n; $j ++) {
                // 依次找到最小值对应的索引 k
                if($data[$j] < $min) {
                    $min = $data[$j];
                    $k = $j;
                }
            }
            if($k != $i) {
                $this->swap($k, $i, $data);
            }
        }
        return $data;
    }
}

$res = (new SelectSort())->run((new Generate(100))->randNumberArray());
echo json_encode($res);

2.4 冒泡排序

冒泡排序是一种基本的排序算法,它的原理是比较相邻元素的大小并交换位置,重复该过程直到所有元素排序完毕

具体步骤如下:

  • 从第一个元素开始,依次比较相邻两个元素的大小(如果是升序,则比较前一个元素是否大于后一个元素;如果是降序,则比较前一个元素是否小于后一个元素),如果不符合要求,则交换它们的位置。

  • 继续比较下一个相邻元素,直到最后一个元素,此时最大或最小的元素已经排在了最后。

  • 重复以上步骤,每次比较的元素数减少1,直到所有的元素都排序完成。

冒泡排序的算法复杂度是O(n²),在数据量比较小的场景下,可以使用冒泡排序,但对于大量数据的排序,建议使用其他更高效的排序算法。

class BubbleSort {

    public function swap($i, $j, &$data) {
        $tmp = $data[$i];
        $data[$i] = $data[$j];
        $data[$j] = $tmp;
    }

    public function run($data)
    {
        $n = count($data);
        for ($i = 0; $i < $n; $i++) {
            for($j = $i + 1; $j < $n; $j++) {
                if($data[$j] < $data[$i]) {
                    $this->swap($j, $i, $data);
                }
            }
        }
        return $data;
    }
}

$res = (new BubbleSort())->run((new Generate(100))->randNumberArray());
echo json_encode($res);

总结

以上就是关于本篇文章介绍的内容,用PHP实现经典的4种排序算法,喜欢点个收藏关注吧。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/447011.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python批量梯度下降法的举例

梯度下降法 梯度下降法是一种常用的优化算法&#xff0c;用于求解目标函数的最小值。其基本思想是&#xff0c;通过不断地朝着函数梯度下降的方向更新参数&#xff0c;直到找到函数的最小值。 具体来说&#xff0c;假设我们有一个可导的目标函数 f ( x ) f(x) f(x)&#xff…

项目五:使用路由器构建园区网

使用路由器构建园区网 1、新建拓扑2、配置交换机与主机3、配置路由交换机并进行通信4、通信测试5、配置路由器并进行通信测试1、配置路由器R-12、配置路由器R-2、R-33、通信测试 1、新建拓扑 依次添加四台主机&#xff0c;两台交换机&#xff0c;型号为S3700。两台路由交换机&…

体制内干部职务职级及领导干部排序对应关系大全

请点击↑关注、收藏&#xff0c;本博客免费为你获取精彩知识分享&#xff01;有惊喜哟&#xff01;&#xff01; 一、公务员级别对应关系 &#xff08;一&#xff09;综合管理公务员职务与职级 1、职务分为10级&#xff0c;包括&#xff1a;正国职、副国职、正部职、副部职、正…

【WSN定位】基于加权双曲线的Dvhop定位算法【Matlab代码#16】

文章目录 1. 原始Dvhop定位2. 基于双曲线的Dvhop定位3. 对原始模型加权4. 部分代码5. 结果展示6. 资源获取7. 参考文献 1. 原始Dvhop定位 可参考Dvhop定位算法 2. 基于双曲线的Dvhop定位 双曲线定位算法是一种通过将待定位节点定位在以锚节点为焦点、两锚节点之间距离为焦距…

字符集与字符编码(ASCII、GBK、UNICODE)

1 常见编码 1.1 单字节编码&#xff1a;ASCII ASCII使用1个字节&#xff08;8个bit&#xff09;来记录一组常用字符&#xff0c;见下表&#xff1a; 例如其中字母a的二进制位&#xff1a;1100 001 97&#xff0c;那么a在计算机中就可以用1100001来保存。 注意上表中其实只…

【02-Java Web先导课】-Tomcat服务器的下载与安装

文章目录 前言一、Tomcat服务器&#xff08;apache-tomcat-8.5.28&#xff09;的 下载1、下载地址 二、Tomcat服务器的安装1、Tomcat目录结构2、Tomcat的启动与停止4、Tomcat启动成功后的测试 免责声明&#xff1a; 前言 Tomcat主要实现了Java EE中的Servlet、JSP规范&#xf…

【Python爬虫项目实战三】Ddddocr识别Ocr过开放猫验证码(接Authorization认证更新)

目录 &#x1f347;前言&#x1f34d;验证码识别的几个方法&#x1f965;百度AI开放平台&#x1f965;Ddddocr&#x1f991;分析验证码位数&#x1f991;获取验证码接口&#x1f991;算法识别匹配&#x1f991;请求登陆接口 &#x1f34b;总结&#xff1a; &#x1f347;前言 …

Doris(13):数据模型

在 Doris 中&#xff0c;数据以表&#xff08;Table&#xff09;的形式进行逻辑上的描述。一张表包括行&#xff08;Row&#xff09;和列&#xff08;Column&#xff09;。Row即用户的一行数据。Column 用于描述一行数据中不同的字段。 Column可以分为两大类&#xff1a;Key&a…

Java双亲委派和类加载器

Java双亲委派和类加载器 Java类生命周期主要内容类加载器的分类Bootstrap ClassLoader非Bootstrap ClassLoaderExtension ClassLoaderApplication ClassLoaderUser ClassLoader 类加载的命名空间问题提出双亲委派机制问题解答 破坏双亲委派破坏双亲委派-第一次破坏双亲委派-第二…

【MySQL】GROUP BY分组子句与联合查询的使用详解

目录 前篇都在这里喔~ MySQL的增删改查 MySQL数据库约束和聚合函数的使用 1.GROUP BY子句 练习表如下&#xff1a; 1.查询不包含董事长的平均工资 2.按照角色分组计算平均工资 3.过滤掉平均工资大于一万的角色 4.♥过滤数据♥ 2.联合查询 以下列表作为依据 1.内连接 …

(十二)rk3568 NPU 中部署自己训练的模型,(1)使用yolov5训练自己的数据集-环境搭建部分

rk3568中带有0.8T算力的NPU&#xff0c;可以完成一些轻量级的图像识别任务。 本文向零基础人员介绍从windows中搭建训练环境&#xff0c;模型训练、模型转换到rknn模型部署到电路板上全部过程。 rk3568npu支持caffe、darknet、onnx、pytorch、tensorflow等多种框架。 本人使用…

springboot+vue企业人事人力资源管理系统java公司员工出差考勤办公OA系统

“简易云”是这个系统的名字 &#xff08;6&#xff09;系统管理&#xff1a;主要下拉分为角色管理、菜单管理&#xff1b; 角色管理&#xff1a;此页面可对角色进行增删改查操作&#xff0c;可修改不同角色的权限&#xff1b; 菜单管理&#xff1a;此页面可配置系统可展示的菜…

linux学习记录 和文件系统相关的命令

记录过程&#xff0c;会有错误,硬链接与软链接哪里可能没有说清楚 文件,目录操作命令 pwd 获取当前处于哪个目录当中&#xff0c;返回的是绝对路径 [rootlocalhost home]# pwd /homecd cd 相对/绝对路径 切换目录的&#xff0c;change directory .代表当前目录 …代表上一级…

【C++学习】类和对象--对象特性(1)

构造函数和析构函数 对象的初始化和清理是两个非常重要的安全问题 一个对象或变量没有初始状态&#xff0c;对其使用后果是未知的 使用完一个对象或变量&#xff0c;没有及时清理&#xff0c;也会造成一定的安全问题 C利用构造函数和析构函数解决上述问题&#xff0c;这两个函数…

排序 Comparable 和 Comparator 区别所在

在 Java 中&#xff0c;Comparable 和Comparator 都是用来元素排序的&#xff0c;但是本质不用。我们从几点开始分析。 1.字面含义 Comparable 中文翻译是”比较“&#xff0c;以 able 结尾 说明它具有某种能力。 Comparator 中文翻译是”比较器“&#xff0c;以 or 结尾 表明…

【C++ 二十】STL:遍历、查找、排序、拷贝和替换、算术生成、集合算法

STL&#xff1a;遍历、查找、排序、拷贝和替换、算术生成、集合算法 文章目录 STL&#xff1a;遍历、查找、排序、拷贝和替换、算术生成、集合算法前言1 常用遍历算法1.1 for_each1.2 transform 2 常用查找算法2.1 find2.2 find_if2.3 adjacent_find2.4 binary_search2.5 count…

室内人员定位系统源码,采用java语言+UWB定位技术开发

运用UWB定位技术开发的人员定位系统源码 文末获取联系 本套系统运用UWB定位技术开发的高精度人员定位系统&#xff0c;通过独特的射频处理&#xff0c;配合先进的位置算法&#xff0c;可以有效计算复杂环境下的人员与物品的活动信息。 系统提供位置实时显示、历史轨迹回放、人…

循序渐进,学会用pyecharts绘制瀑布图

循序渐进&#xff0c;学会用pyecharts绘制瀑布图 瀑布图简介 瀑布图(Waterfall Plot)是由麦肯锡顾问公司所独创的图表类型&#xff0c;因为形似瀑布流水而称之为瀑布图。 瀑布图采用绝对值与相对值结合的方式&#xff0c;适用于表达多个特定数值之间的数量变化关系。当用户想…

本地Nacos设置脚本命令启动

一、起因&#xff1a; 每次启动都要找到位置写一遍命令费劲。 1、可设置开机启动 2、可设置脚本自动 二、配置脚本&#xff1a; 1、这是我nacos的位置 用bat命令启动一个cmd命令行&#xff0c;然后在里面执行两天命令。 ①命令一&#xff1a;打开指定路径 ②命令二&#xf…

Java图书借阅管理系统详细设计和实现

基于JavaSpringHtml的图书借阅管理系统详细设计和实现 博主介绍&#xff1a;5年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 超级帅帅吴 Java毕设项目精品实战案例《500套》 欢迎点赞 收藏 ⭐留言 文末获取源…