首页 php教程 php手册 浅谈PHP第二弹---经典算法的运用(冒泡排序和快速排序)

浅谈PHP第二弹---经典算法的运用(冒泡排序和快速排序)

Jun 13, 2016 am 10:48 AM
php 冒泡 快速 思想 排序 算法 经典 说说 运用 首先

首先说说冒泡排序的思想,那很多同学会问什么是冒泡排序法呢?


下面我来解释下:

所谓的冒泡排序法,就是依次比较相邻的两个数,将小数放在前面,大数放在后面。即在第一趟:首先比较第1个和第2个数,将小数放前,大数放后。然后比较第2个数和第3个数,将小数放前,大数放后,如此继续,直至比较最后两个数,将小数放前,大数放后。至此第一趟结束,将最大的数放到了最后。在第二趟:仍从第一对数开始比较(因为可能由于第2个数和第3个数的交换,使得第1个数不再小于第2个数),将小数放前,大数放后,一直比较到倒数第二个数(倒数第一的位置上已经是最大的),第二趟结束,在倒数第二的位置上得到一个新的最大数(其实在整个数列中是第二大的数)。如此下去,重复以上过程,直至最终完成排序。


咱们来看个例子:
有一个数组array(23,34,12,56,43,98,89),下面我们来使用冒泡排序法来对其元素进行排序.
$arr = Array(23,34,12,56,43,98,89);
for($i=0;$i for($j=0;$j if($arr[$j]>$arr[$j+1]){
$tmp = $arr[$j];
$arr[$j] = $arr[$j+1];
$arr[$j+1] = $tmp;
}
}
}
?>

在上面的例子中,里面的for循环,是将本数组中的所有元素依次两两相比,也就是将数组中的第一个元素和第二个元素相比,第二个元素与第三个元素相比,
依此类推,直到数组的倒数第二个元素与最后一个元素相比,如果前面的元素大于后面的元素就让前面的元素与后面的元素位置交换,
那我们想,怎么让数组中的两个元素位置交换呢,
我们可以使用一个中间的容器变量来解决这个问题,
也就是将需要交换的第一个变量的值放入容器变量,然后将需要交换的第二个变量的值赋给第一个变量,再将容器变量中的值赋给第二个变量即可.


为了让大家更深刻的理解,请看下面的模拟图:

第一步:声明一个中间容器变量$tmp:

第二步:将$arr[$j]的值赋给$tmp

第三步:将$arr[$j+1]赋值给$arr[$j]

第四步:将中间变量的值赋给$arr[$j+1],完成交换

依次类推,一直到数组的倒数第二个元素与最后一个元素比较完成.总共比较count($arr)-1次
至此,我们数组的第一趟排序也就完成,此时数组中最大的数已经放到了数组的最后.也就是说,内层的for循环已经执行完成. www.2cto.com
接下来我们需要进行第二趟,第三趟....排序,每排一趟,出一个最大的数放在数组后面,只要排完,总共排count($arr)趟.
说到这里,大家是不是明白外层for循环的意思了呢!
好,我们思考一个问题,如果数组内的元素两两比较完,每比较一趟排出一个最大数,
那我们是不是在下趟比较的时候,不执行和上趟排出来的最大数的比较呢,
也就是说,第一趟排序完,98已经被放到了数组的最后,下趟排序就无需再把98拿来比较了,这样会提高效率,节省资源,
因此我们可以这样写:
$arr = Array(23,34,12,56,43,98,89);
for($i=0;$i for($j=0;$j if($j==count($arr)-1){
continue;
}
if($arr[$j]>$arr[$j+1]){
$tmp = $arr[$j];
$arr[$j] = $arr[$j+1];
$arr[$j+1] = $tmp;
}
}
}
?>

上述代码中,内层循环执行次数变成了count($arr)-$i,
也就是说每趟把数组内的所有元素两两比较完之后,下趟再进行此排序时,排序的次数会减一,
也就是排除上一趟比较得出的最大的数的比较,这样一来,效率会提升不少,
我们可以使用php的内建函数microtime()在执行排序前执行一次,在排序后执行一次,将两次的时间相减,即得出运算时间,
通过比较可以得出冒泡排序的第二种排序方法的效率要高于第一种排序方法,但不是很明显,大家下来可以验证下,这里就不多讲了.

下面我们使用快速排序法对以上数组进行排序:
$arr = Array(23,34,12,56,43,98,89);
function quick($arr){
$left = array();
$right = array();
if(count($arr) return $arr;
}
for($i=1;$i if($arr[0]>$arr[$i]){
$left[] = $arr[$i];
}else{
$right[] = $arr[$i];
}
}
$left = quick($left);
$right = quick($right);
return array_merge($left,array($arr[0]),$right);
}
?>


所谓快速排序,就是在$arr数组中任意取一个值作为中间值,然后将这个值与数组内其他所有元素相比较,比这个值小的放到左边,比这个值大的放到这个值的右边, 此时完成一趟排序.以此类推,再将这个值左边的数进行上述排序,同样对右边的数进行上述排序.直到将所有的值都比较完.

我们来看上面的代码:
首先使用快速排序的理念就需要使用递归,说到递归,就是用函数自己调用自己,逐层深入,最后将拿到的值返回的思想.
下面我们来看,首先我们需要自定义一个函数quick(),让此函数自己调用自己.
这里中间值我们用$arr[0],这个是随意取的,不是必须的,
为了让大家思路清晰,我们先定义两个空数组,就相当于两个杯子,
让$arr[0]与数组内所有的值进行比较,比$arr[0]小的值放到第一个杯子中,比$arr[0]大的放到第二个杯子中,在程序中分别为$left和$right,
我们判断,如果给定的数组元素只有一个或为空,此数组将被quick函数返回,不再执行下面的内容,
接下来我们对数组进行遍历,并用遍历出来的值分别与$arr[0]进行比较,比$arr[0]小的值存入$left数组,比$arr[0]大的的值存入$right数组,此时完成一趟排序,
接下来再对$left数组和$right数组进行同样的操作,也就是调用函数自己,将$left数组和$right数组传入,直到$left数组或$right数组的数组元素为一个时,不再调用自己,直接返回,
最后将左边的数组,$arr[0],$right数组合并,即可得到最终的排序结果.

修正:
纠正效率方面的问题,在测试效率的时候,发生一个错误,导致效率测试不准确,经各位同学提醒,又一再测试,最终发现对此数组排序时运用快速排序的运算效率与冒泡排序的第二种相差不多,但是冒泡的第一种还是要比第二种明显的高一些,这个测试结果只能作为参考,要精确地算出每种算法的效率,需要对算法内部进行排序次数的统计.
再次感谢各位同学的关注,以及对于此问题的纠正,这是一个开放的平台,请大家畅所欲言,多多交流,共同进步...



摘自 zdrjlamp

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

热门话题

Java教程
1660
14
CakePHP 教程
1416
52
Laravel 教程
1310
25
PHP教程
1260
29
C# 教程
1233
24
您如何在PHP中解析和处理HTML/XML? 您如何在PHP中解析和处理HTML/XML? Feb 07, 2025 am 11:57 AM

本教程演示了如何使用PHP有效地处理XML文档。 XML(可扩展的标记语言)是一种用于人类可读性和机器解析的多功能文本标记语言。它通常用于数据存储

在PHP API中说明JSON Web令牌(JWT)及其用例。 在PHP API中说明JSON Web令牌(JWT)及其用例。 Apr 05, 2025 am 12:04 AM

JWT是一种基于JSON的开放标准,用于在各方之间安全地传输信息,主要用于身份验证和信息交换。1.JWT由Header、Payload和Signature三部分组成。2.JWT的工作原理包括生成JWT、验证JWT和解析Payload三个步骤。3.在PHP中使用JWT进行身份验证时,可以生成和验证JWT,并在高级用法中包含用户角色和权限信息。4.常见错误包括签名验证失败、令牌过期和Payload过大,调试技巧包括使用调试工具和日志记录。5.性能优化和最佳实践包括使用合适的签名算法、合理设置有效期、

解释PHP中的晚期静态绑定(静态::)。 解释PHP中的晚期静态绑定(静态::)。 Apr 03, 2025 am 12:04 AM

静态绑定(static::)在PHP中实现晚期静态绑定(LSB),允许在静态上下文中引用调用类而非定义类。1)解析过程在运行时进行,2)在继承关系中向上查找调用类,3)可能带来性能开销。

php程序在字符串中计数元音 php程序在字符串中计数元音 Feb 07, 2025 pm 12:12 PM

字符串是由字符组成的序列,包括字母、数字和符号。本教程将学习如何使用不同的方法在PHP中计算给定字符串中元音的数量。英语中的元音是a、e、i、o、u,它们可以是大写或小写。 什么是元音? 元音是代表特定语音的字母字符。英语中共有五个元音,包括大写和小写: a, e, i, o, u 示例 1 输入:字符串 = "Tutorialspoint" 输出:6 解释 字符串 "Tutorialspoint" 中的元音是 u、o、i、a、o、i。总共有 6 个元

什么是PHP魔术方法(__ -construct,__destruct,__call,__get,__ set等)并提供用例? 什么是PHP魔术方法(__ -construct,__destruct,__call,__get,__ set等)并提供用例? Apr 03, 2025 am 12:03 AM

PHP的魔法方法有哪些?PHP的魔法方法包括:1.\_\_construct,用于初始化对象;2.\_\_destruct,用于清理资源;3.\_\_call,处理不存在的方法调用;4.\_\_get,实现动态属性访问;5.\_\_set,实现动态属性设置。这些方法在特定情况下自动调用,提升代码的灵活性和效率。

PHP和Python:比较两种流行的编程语言 PHP和Python:比较两种流行的编程语言 Apr 14, 2025 am 12:13 AM

PHP和Python各有优势,选择依据项目需求。1.PHP适合web开发,尤其快速开发和维护网站。2.Python适用于数据科学、机器学习和人工智能,语法简洁,适合初学者。

PHP行动:现实世界中的示例和应用程序 PHP行动:现实世界中的示例和应用程序 Apr 14, 2025 am 12:19 AM

PHP在电子商务、内容管理系统和API开发中广泛应用。1)电子商务:用于购物车功能和支付处理。2)内容管理系统:用于动态内容生成和用户管理。3)API开发:用于RESTfulAPI开发和API安全性。通过性能优化和最佳实践,PHP应用的效率和可维护性得以提升。

PHP:网络开发的关键语言 PHP:网络开发的关键语言 Apr 13, 2025 am 12:08 AM

PHP是一种广泛应用于服务器端的脚本语言,特别适合web开发。1.PHP可以嵌入HTML,处理HTTP请求和响应,支持多种数据库。2.PHP用于生成动态网页内容,处理表单数据,访问数据库等,具有强大的社区支持和开源资源。3.PHP是解释型语言,执行过程包括词法分析、语法分析、编译和执行。4.PHP可以与MySQL结合用于用户注册系统等高级应用。5.调试PHP时,可使用error_reporting()和var_dump()等函数。6.优化PHP代码可通过缓存机制、优化数据库查询和使用内置函数。7

See all articles