1、冒泡排序

  冒泡排序其实是基于“交换”。每次从第一个记录开始,一、二两个记录比较,大的往后放,二三两个记录比较...依次类推,这就是一趟冒泡排序。每一趟冒泡排序后,无序序列中值最大的记录冒到序列末尾,所以称之为冒泡排序

function BubbleSort(&$_arr){
$len=count($_arr);
     //外循环控制轮数
for($j=$len;$j>0;$j--){
         //控制比较次数
for($i=0;$i<$j-1;$i++){
if($_arr[$i]>$_arr[$i+1]){
$temp=$_arr[$i];
$_arr[$i]=$_arr[$i+1];
$_arr[$i+1]=$temp;
}
}
}
}

效率分析

相对于简单选择排序,冒泡排序交换次数明显更多。它是通过不断地交换把最大的数冒出来。

冒泡排序平均时间和最坏情况下(逆序)时间为o(n^2),最佳情况下虽然不用交换,但比较的次数没有减少,时间复杂度仍为o(n^2)。此外冒泡排序是稳定的

2、选择排序

  给定待排序序列A[ 1......n ] ,选择出第i小元素,并和A[i]交换,这就是一趟简单选择排序。固定值、然后交换索引

  选择排序的思想非常直接,不是要排序么?那好,我就从所有序列中先找到最小的,然后放到第一个位置。之后再看剩余元素中最小 的,放到第二个位置……以此类推,就可以完成整个的排序工作了。可以很清楚的发现,选择排序是固定位置,找元素。相比于插入排序的固定元素找位置,是两种 思维方式。不过条条大路通罗马,两者的目的是一样的

function SelectSort(&$_arr){
$len = count($_arr);
for($i=0; $i<$len; $i++){
$k = $i;
for($j=$i+1; $j<$len; $j++){
if ($_arr[$k] > $_arr[$j])
$k = $j;
if ($k != $i){
$tmp = $_arr[$i];
$_arr[$i] = $_arr[$k];
$_arr[$k] = $tmp;
}
}
}
}

性能分析

  简单选择排序所需进行记录移动的操作次数较少,这一点上优于冒泡排序,最佳情况下(待排序序列有序)记录移动次数为0,最坏情况下(待排序序列逆序)记录移动次数n-1。外层循环进行了n-1趟选择,第i趟选择要进行n-i次比较。每一趟的时间:n-i次的比较时间+移动记录的时间(为一常数0或1,可以忽略)。总共进行了n-1趟。忽略移动记录的时间,所以总时间为(n-1)*(n-i)=n^2-(i+1)*n+i。时间复杂度为O(n^2)。不管是最坏还是最佳情况下,比较次数都是一样的,所以简单选择排序平均时间、最坏情况、最佳情况时间复杂度都为O(n^2)

直接选择排序是一个就地排序,直接选择排序是不稳定的

3、插入排序

  给定待排序序列A[ 1.....n ],现假设A[1...i]已经有序,那么我们取出A[i+1]插入到序列A[1...i].这样有序序列记录数就增加了1.如此重复上述操作,不断取出记录插入有序序列,直到A[n]插入到有序序列,排序完成

  从有序序列的最后一个元素开始查找,边查找边移动元素,而不是先找到插入位置再移动元素,这样提高了效率。

function InsertSort(&$_arr){
$len = count($_arr);
for($i=1; $i<$len; $i++){
$tmp = $_arr[$i];
$j = $i-1; while($_arr[$j] > $tmp && $j>=0){
$_arr[$j+1] = $_arr[$j];
$_arr[$j] = $tmp;
$j--; }
}
}

效率分析

  容易看出,要插入的记录个数为n-1,其中关键字的比较次数和记录移动次数是依赖于给出的待排序序列是否基本有序。在最佳情况下(待排序序列有序),比较次数和移动次数时间为o(1),所以时间复杂度为o(n).在最坏情况下(待排序序列逆序)和平均时间均为o(n^2).从上述分析中可以看出,直接插入排序适合记录数比较少、给定序列基本有序的情况。熟悉了排序过程我们发现,直接插入排序是一种稳定的原地排序算法

4、快速排序

  快速排序是冒泡排序的一种改进,冒泡排序排完一趟是最大值冒出来了,那么可不可以先选定一个 值,然后扫描待排序序列,把小于该值的记录和大于该值的记录分成两个单独的序列,然后分别对这两个序列进行上述操作。这就是快速排序,我们把选定的那个值 称为枢纽值,如果枢纽值为序列中的最大值,那么一趟快速排序就变成了一趟冒泡排序

function QuickSort($_arr){
$len=count($_arr);
if($len <= 1) return $_arr; $base = $_arr[0];
$left_arr =$right_arr=array(); for($i=1; $i<$len; $i++){
if($_arr[$i]<= $base){
$left_arr[]=$_arr[$i];
}else{
$right_arr[]=$_arr[$i];
}
} $left_arr=QuickSort($left_arr);
$right_arr=QuickSort($right_arr); $arr=array_merge($left_arr, array($base), $right_arr);
return $arr;
}

效率分析

  最佳情况下,每次划分都是对称的,由于枢纽值不再考虑,所以得到的两个子问题的大小不可能大于n/2,同时一趟快速排序时间为o(n),所以运行时间递归表达式:T(n)<=2T(n/2)+o(n)。这个递归式的解法请参考下一篇博客中归并排序效率分析。其解为T(n)=o(n*logn)。

  最坏情况下,每次划分都很不对称,T(n)=T(n-1)+o(n),可以用递归树来解,第i层的代价为n-i+1.总共有n层。把每一层代价加起来有n-1个n相加。所以这个递归式的解为T(n)=o(n^2),此时就是冒泡排序。

还有两个概念要了解一下

1. 内排序和外排序

内排序,参加排序的数据量不大,在排序过程中可以将所有参加排序的数据存放在内存中处理的排序方法。

外排序,参加排序的数据量很大,以至于内存不足以一次存放全部数据,在排序过程中需要通过内存与外存之间的数据交换来达到排序目的的排序方法。

2. 稳定性排序与非稳定性排序

参加排序的项称为排序码或者排序项。

这个概念是针对的是有多个相同的排序项参加排序的情况。

若采用排序方法排序后这些相同的排序项的相对位置与排序之前保持不变,则称此排序方法是稳定性排序,否则为非稳定性排序。

例如,参加排序的依次是:a1 = 3, a2 = 6, a3 = 18, a4 = 3, a5 = 18;

若是稳定性排序,则排序结果一定是:

a1 = 3, a4 = 3, a2 = 6, a3 = 18, a5 = 18;

若是非稳定性排序,则排序结果可能会是:

a4 = 3, a1 = 3, a2 = 6, a3 = 18, a5 = 18;

这样a1 和a4 的相对位置改变。

PHP实现4种排序算法的更多相关文章

  1. 几种排序算法的学习,利用Python和C实现

    之前学过的都忘了,也没好好做过总结,现在总结一下. 时间复杂度和空间复杂度的概念: 1.空间复杂度:是程序运行所以需要的额外消耗存储空间,一般的递归算法就要有o(n)的空间复杂度了,简单说就是递归集算 ...

  2. 秒杀9种排序算法(JavaScript版)

    一:你必须知道的 1> JS原型 2> 排序中的有序区和无序区 3> 二叉树的基本知识 如果你不知道上面三个东西,还是去复习一下吧,否则,看下面的东西有点吃力. 二:封装丑陋的原型方 ...

  3. PHP的几种排序算法的比较

    这里列出了几种PHP的排序算法的时间比较的结果,,希望对大家有所帮助 /* * php 四种排序算法的时间与内置的sort排序比较 * 3000个元素,四种算法的排序所用的时间比较 * 冒泡排序 85 ...

  4. 学习Java绝对要懂的,Java编程中最常用的几种排序算法!

    今天给大家分享一下Java中几种常见的排序算法的Java代码 推荐一下我的Java学习羊君前616,中959,最后444.把数字串联起来!     ,群里有免费的学习视频和项目给大家练手.大神有空时也 ...

  5. C#常用8种排序算法实现以及原理简介

    public static class SortExtention { #region 冒泡排序 /* * 已知一组无序数据a[1].a[2].--a[n],需将其按升序排列.首先比较a[1]与a[2 ...

  6. 排序—时间复杂度为O(n2)的三种排序算法

    1 如何评价.分析一个排序算法? 很多语言.数据库都已经封装了关于排序算法的实现代码.所以我们学习排序算法目的更多的不是为了去实现这些代码,而是灵活的应用这些算法和解决更为复杂的问题,所以更重要的是学 ...

  7. java算法03 - 常用的8种排序算法

    Java常用的八种排序算法: 插入排序 - 直接插入排序 每次将待排序的记录按照关键字的大小,插入到前面已经排好序的记录的适当位置.直到全部记录插入完成. 代码实现 /** * 直接插入排序 O(n^ ...

  8. 用 C 语言描述几种排序算法

    排序算法是最基本且重要的一类算法,本文基于 VS2017,使用 C 语言来实现一些基本的排序算法. 一.选择排序 选择排序,先找到数组中最小的元素,然后将这个元素与数组的第一个元素位置互换(如果第一个 ...

  9. 【C++】四种排序算法的时间比较

    四种排序算法的时间比较 [注]clock函数对输入(用户输入)元素N排序的计时 #include<iostream> #include<time.h> using namesp ...

  10. 几种排序算法及Java实现排序的几种方式

    几种排序算法 下面的例子介绍了4种排序方法: 冒泡排序, 选择排序, 插入排序, 快速排序 package date201709.date20170915; public class SortUtil ...

随机推荐

  1. mysql错误:this authentication plugin is not supported

    this authentication plugin is not supported 应用程序连接mysql docker一直报错:this authentication plugin is not ...

  2. LeetCode: Implement strStr() [027]

    [题目] Implement strStr(). Returns a pointer to the first occurrence of needle in haystack, or null if ...

  3. 操作系统的启动与引导问题 BIOS、UEFI、MBR、GPT

    关于ISO.WIM.GHO三者的正确理解. ISO(Isolation)文件一般以ISO为扩展名,是复制光盘上全部信息而形成的镜像文件. WIM是英文Microsoft Windows Imaging ...

  4. Html5 中获取镜像图像 - 解决 WebGL 中纹理倒置问题

    Html5 中获取镜像图像 - 解决 WebGL 中纹理倒置问题 太阳火神的漂亮人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商业用途-保持一致& ...

  5. web 实时通信的方法总结

    1.Web端即时通讯技术 即时通讯技术简单的说就是实现这样一种功能:服务器端可以即时地将数据的更新或变化反应到客户端,例如消息即时推送等功能都是通过这种技术实现的. 但是在Web中,由于浏览器的限制, ...

  6. IOS Xib使用——为控制器添加Xib文件

    Xib文件是一个轻量级的用来描述局部界面的文件,它与StoryBoard类似,都是使用Interface Bulider工具进行编辑.但是StoryBoard是重量级的,它是用来描述整个软件的多个界面 ...

  7. centos7 JDK1.8

    安装之前先检查一下系统有没有自带open-jdk rpm -qa |grep java rpm -qa |grep jdk 卸载找出的已安装Java相关rpm文件:rpm -e --nodeps 重新 ...

  8. Android studio 2.0--android增量更新的那些事

    用了这么久的AS 2.0预览版本号.4.7日谷歌最终公布了android studio 2.0正式版,小编当日便下载了.玩了一下.感觉第二次build编译明显快了,并且好像并没有又一次部署apk.经过 ...

  9. android中的数据库操作(SQLite)

    android中的数据库操作 android中的应用开发很难避免不去使用数据库,这次就和大家聊聊android中的数据库操作. 一.android内的数据库的基础知识介绍 1.用了什么数据库   an ...

  10. 自定义UITableViewCell 的delete按钮

    自定义UITableViewCell上的delete按钮 滑动列表行(UITableViewCell)出现删除按钮时,默认是英文“delete”,这份代码片段能够将“delete”变成中文”删除“,甚 ...