php几种常见排序算法
<?php
//从时间上来看,快速排序和归并排序在时间上比较有优势,
//但是也比不上sort排序,归并排序比较占用内存!
$arr = [4,6,1,2,3,89,56,34,56,23,65];
/**
* 冒泡排序
* 它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。
* 走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成
*/
function BubbleSortq($arr)
{
$len = count($arr);
//设置一个空数组 用来接收冒出来的泡
for ($i = 1; $i < $len; $i++) //该层循环控制 需要冒泡的轮数
{
$flag = false; //本趟排序开始前,交换标志应为假
//该层循环用来控制每轮 冒出一个数 需要比较的次数
for ($k = 0; $k < $len - $i - 1; $k++)
{
//从小到大排序
if ($arr[$k] > $arr[$k + 1])
{
$tmp = $arr[$k + 1];
$arr[$k + 1] = $arr[$k];
$arr[$k] = $tmp;
$flag = true;
}
}
if(!$flag) return $arr;
}
}
// print_r(BubbleSort($arr));
/**
* 选择排序算法
* 每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。
* 选择排序是不稳定的排序方法(比如序列[5, 5, 3]第一次就将第一个[5]与[3]交换,导致第一个5挪动到第二个5后面)
*/
function SelectSort($arr)
{
//定义进行交换的变量
$temp = 0;
for ($i = 0; $i < count($arr) - 1; $i++)
{
$minval = $arr[$i];//假设$minval就是最小的值
$minvalIndex = $i;//最小值的下标
for ($j = $i + 1; $j < count($arr); $j++)
{
if ($minval > $arr[$j])//从小到大排列
{
$minval = $arr[$j];//找最小值
$minvalIndex = $j;
}
}
$temp = $arr[$i];
$arr[$i] = $arr[$minvalIndex];
$arr[$minvalIndex] = $temp;
}
return $arr;
}
// print_r(SelectSort($arr));
/**
* 插入算法
* 每步将一个待排序的纪录,按其关键码值的大小插入前面已经排序的文件中适当位置上,直到全部插入完为止。
* 算法适用于少量数据的排序,时间复杂度为O(n^2)。是稳定的排序方法。
*/
function insertSort($arr)//从小到大排列
{
//先默认$arr[0],已经有序,是有序表
for ($i = 1; $i < count($arr); $i++)
{
$insertval = $arr[$i];//$insertval是准备插入的数
$insertIndex = $i - 1;//有序表中准备比较的数下标
while ($insertIndex >= 0 && $insertval < $arr[$insertIndex])
{
$arr[$insertIndex + 1] = $arr[$insertIndex];//将数组往后挪
$insertIndex--;//将下标往前挪,准备与前一个进行比较
}
if ($insertIndex + 1 !== $i)
{
$arr[$insertIndex + 1] = $insertval;
}
}
return $arr;
}
// print_r(insertSort($arr));
/*
* 快速排序法
* 通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,
* 然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
*/
function quickSort($arr)
{
//判断是否为数组
if (is_array($arr))
{
return false;
}
//如果数组长度为1直接返回
if (!isset($arr[1]))
{
return $arr;
}
$mid = $arr[0]; //获取一个用于分割的关键字,一般是首个元素
$leftArray = array();
$rightArray = array();
foreach ($arr as $v)
{
if ($v > $mid)
{
$rightArray[] = $v; //把比$mid大的数放到一个数组里
}
if($v < $mid)
{
$leftArray[] = $v; //把比$mid小的数放到另一个数组里
}
}
$leftArray = quickSort($leftArray); //把比较小的数组再一次进行分割
$leftArray[] = $mid; //把分割的元素加到小的数组后面,不能忘了它哦
$rightArray = quickSort($rightArray); //把比较大的数组再一次进行分割
return array_merge($leftArray,$rightArray); //组合两个结果
}
// print_r(quickSort($arr));
/**
* 归并排序
* 归并排序是指将两个或两个以上有序的数列(或有序表),合并成一个仍然有序的数列(或有序表)。
* 这样的排序方法经常用于多个有序的数据文件归并成一个有序的数据文件。
*/
function mergeSort(&$arr)
{
$len = count($arr);//求出数组长度
mSort($arr,0,$len - 1);
return $arr;
}
//实际实现归并排序的程序
function mSort(&$arr,$left,$right)
{
if ($left < $right)
{
//说明子序列内存在多余1个的元素,那么需要拆分,分别排序,
//合并计算拆分的位置,长度/2 取整
$center = floor(($left + $right) / 2);
//递归调用对左边进行再次排序
mSort($arr, $left, $center);
//递归调用对右边进行再次排序
mSort($arr, $center + 1, $right);
//合并排序结果
mergeArray($arr, $left, $center, $right);
}
}
//讲两个有序数组合并成一个有序数组
function mergeArray(&$arr, $left, $center, $right)
{
//设置两个起始位置标记
$a_i = $left;
$b_i = $center + 1;
while ($a_i <= $center && $b_i <= $right)
{
//当数组A和数组B都没有越界时
if ($arr[$a_i] < $arr[$b_i])
{
$temp[] = $arr[$a_i++];
}
else
{
$temp[] = $arr[$b_i++];
}
}
//判断 数组A内的元素是否都用完了,没有的话将其全部插入到C数组内
while ($a_i <= $center)
{
$temp[] = $arr[$a_i++];
}
//判断 数组A内的元素是否都用完了,没有的话将其全部插入到C数组内
while ($b_i <= $right)
{
$temp[] = $arr[$b_i++];
}
//将$arrC内排序好的部分,写入到$arr内
for ($i = 0, $len = count($temp); $i < $len; $i++)
{
$arr[$left + $i] = $temp[$i];
}
}
// print_r(mergeSort($arr));
/*
* 希尔排序
* 将数组按指定步长分隔成若干子序列,然后分别对子序列进行排序(在这是直接)
*/
function shellSort($arr)
{
$len = count($arr);
$k = floor($len / 2);
while ($k > 0)
{
for ($i = 0; $i < $k; $i++)
{
for ($j = $i; $j < $len, ($j + $k) < $len; $j = $j + $k)
{
if ($arr[$j] > $arr[$j + $k])
{
$tmp = $arr[$j + $k];
$arr[$j + $k] = $arr[$j];
$arr[$j] = $tmp;
}
}
}
$k = floor($k / 2);
}
return $arr;
}
// print_r(shellSort($arr));
/*
*堆排序
*调整子堆的为大根堆的过程,$s为子堆的根的位置,$m为堆最后一个元素位置
*/
function heapAdjust(&$arr, $s, $m)
{
$tmp = $arr[$s];
// 在调整为大根堆的过程中可能会影响左子堆或右子堆
// for循环的作用是要保证子堆也是大根堆
for ($j = 2*$s + 1; $j <= $m; $j = 2*$j + 1)
{
// 找到根节点的左右孩子中的最大者,然后用这个最大者与根节点比较,
// 若大则进行调整,否则符合大根堆的 特点跳出循环
if ($j < $m && $arr[$j] < $arr[$j + 1])
{
$j++;
}
if ($tmp >= $arr[$j] )
{
break;
}
$arr[$s] = $arr[$j];
$s = $j;
}
$arr[$s] = $tmp;
}
// 堆排序
function heapSort($arr)
{
$len = count($arr);
// 依次从子堆开始调整堆为大根堆
for ($i = floor($len / 2 - 1); $i >= 0; $i--)
{
heapAdjust($arr, $i, $len - 1);
}
// 依次把根节点调换至最后一个位置,再次调整堆为大根堆,找到次最大值,
// 依次类推得到一个有序数组
for ($n = $len - 1; $n > 0; $n--)
{
$tmp = $arr[$n];
$arr[$n] = $arr[0];
$arr[0] = $tmp;
heapAdjust($arr, 0, $n - 1);
}
return $arr;
}
print_r(heapSort($arr));
php几种常见排序算法的更多相关文章
- JavaScript版几种常见排序算法
今天发现一篇文章讲“JavaScript版几种常见排序算法”,看着不错,推荐一下原文:http://www.w3cfuns.com/blog-5456021-5404137.html 算法描述: * ...
- Java中几种常见排序算法
日常操作中常见的排序方法有:冒泡排序.快速排序.选择排序.插入排序.希尔排序等. 冒泡排序是一种简单的排序算法.它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数 ...
- 几种常见排序算法之Java实现(插入排序、希尔排序、冒泡排序、快速排序、选择排序、归并排序)
排序(Sorting) 是计算机程序设计中的一种重要操作,它的功能是将一个数据元素(或记录)的任意序列,重新排列成一个关键字有序的序列. 稳定度(稳定性)一个排序算法是稳定的,就是当有两个相等记录的关 ...
- 几种常见排序算法的java实现
一.几种常见的排序算法性能比較 排序算法 最好时间 平均时间 最坏时间 辅助内存 稳定性 备注 简单选择排序 O(n^2) O(n^2) O(n^2) O(1) 不稳定 n小时较好 直接插入排序 O( ...
- Java的几种常见排序算法
一.所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作.排序算法,就是如何使得记录按照要求排列的方法.排序算法在很多领域得到相当地重视,尤其是在大量数据的处理方面. ...
- 几种常见排序算法的基本介绍,性能分析,和c语言实现
本文介绍6种常见的排序算法,以及他们的原理,性能分析和c语言实现: 为了能够条理清楚,本文所有的算法和解释全部按照升序排序进行 首先准备一个元素无序的数组arr[],数组的长度为length,一个交换 ...
- 几种常见排序算法的C++描述
基本的排序算法有如下特点: 1.几种容易的算法都是以O(N2)排序的 2.Shell排序编程简单,其也是以O(N2)排序的,在实践中用的很多 3.复杂的排序算法往往都是按照O(NlogN)尽心排序的 ...
- 【知了堂学习笔记】java 编写几种常见排序算法2
排序的分类: 1.直接选择排序 它的基本思想是:第一次从R[0]~R[n-1]中选取最小值,与R[0]交换,第二次从R[1]~R[n-1]中选取最小值,与R[1]交换,....,第i次从R[i-1]~ ...
- 【知了堂学习笔记】java 编写几种常见排序算法
排序的分类: 一.交换排序 所谓交换,就是根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置,交换排序的特点是:将键值较大的记录向序列的尾部移动,键值较小的记录向序列的前部移动. 1.冒泡 ...
随机推荐
- 646. Maximum Length of Pair Chain 最长的链条长度
[抄题]: You are given n pairs of numbers. In every pair, the first number is always smaller than the s ...
- spring-boot的三种启动方式[z]
https://blog.csdn.net/u011425751/article/details/79507386 有段时间没有写博客了,也在努力的从传统单机开发向分布式系统过度,所以再次做一些笔记, ...
- 解决 ora-28001 密码过期的处理办法
转载自:https://blog.csdn.net/pengyouchuan/article/details/12905623 操作步骤: $sqlplus / as sysdba ALTER PRO ...
- springboot 使用JPA自动生成Entity实体类的方法
1. 2. 3.添加数据库 4. 5. 6. 7.点击OK完成. 8.去掉红色波浪线方法. 9.配置数据源 完成!
- BZOJ1433或洛谷2055 [ZJOI2009]假期的宿舍
BZOJ原题链接 洛谷原题链接 对于每个需要床位的人向他能睡的床连边,然后就是二分图最大匹配模板了. 这里用匈牙利算法. #include<cstdio> #include<cstr ...
- 用TSQL从sqlserve 发布订阅链中删除一张或几张表
一个简单的存储过程,用来实现从一个SQLSERVE 发布订阅链中删除一张或几张表. /* 1.停日志读取代理 2.exec usp_从复制订阅中删除表 'dbtestPub','test1' 3.开日 ...
- HDU 6214.Smallest Minimum Cut 最少边数最小割
Smallest Minimum Cut Time Limit: 2000/2000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Oth ...
- Nginx学习笔记(反向代理&搭建集群)
一.前言 1.1 大型互联网架构演变历程 1.1.1 淘宝技术 淘宝的核心技术(国内乃至国际的 Top,这还是2011年的数据) 拥有全国最大的分布式 Hadoop 集群(云梯,2000左右节点,24 ...
- JDBC - Mysql 8.0.13 连接测试
因为换新的电脑设备,为其安装一些开发需要的应用及环境,下载了新版的Mysql8.0.13,在Eclipse中测试连接时遇到一些新的问题,遂记录. 1. Mysql 5.* 版本JDBC连接 a. 常 ...
- Codeforces Round #536 (Div. 2) E dp + set
https://codeforces.com/contest/1106/problem/E 题意 一共有k个红包,每个红包在\([s_i,t_i]\)时间可以领取,假如领取了第i个红包,那么在\(d_ ...