一:冒泡排序
1:算法步骤
-
比较相邻项的值,如果前者比后者大,交换顺序。
-
进行一轮比较后,最后一个值为最大的值。
-
进行下一轮比较,比上次少比较一项。
-
以此类推,比较剩下最后一项的时候,比较结束。
2:动态演示
3:示例代码
/**
* 冒泡排序
*/
public function bubbleSort($arr)
{
$temp = 0;
//外层循环,只要确定排好n-1个数,则最后一个数自然排好了
for($i=0;$i<count($arr)-1;$i++){
//每次进行一次大循环时,最大数已经在最后了,则下次循环则不用再比较已经排好的数
for($j=0;$j<count($arr)-1-$i;$j++){
if($arr[$j] > $arr[$j+1]){
$temp = $arr[$j];
$arr[$j] = $arr[$j+1];
$arr[$j+1] = $temp;
}
}
}
return $arr;
}
二:选择排序
1:算法步骤
-
首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。
-
再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
-
重复第二步,直到所有元素均排序完毕。
2:动态演示
3:示例代码
/**
* 选择排序
*/
public function selectionSort($arr)
{
$temp=0;
for($i=0;$i<count($arr)-1;$i++){
$minVal = $arr[$i]; //假设$i就是最小值
$minIndex = $i; //记录认为最小值的小标
for($j=$i+1;$j<count($arr);$j++){
if($minVal > $arr[$j]){
$minVal = $arr[$j];
$minIndex = $j;
}
}
$temp = $arr[$i];
$arr[$i] = $arr[$minIndex];
$arr[$minIndex] = $temp;
}
return $arr;
}
三:插入排序
1:算法步骤
-
将第一待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列。
-
从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置。(如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面)。
2:动态演示
3:示例代码
/**
* 插入排序
*/
public function insertionSort($arr)
{
for($i=1;$i<count($arr);$i++){
//insertVal是准备插入的数
$insertVal = $arr[$i];
//准备先和insertIndex比较
$insertIndex = $i-1;
while($insertIndex>=0 && $insertVal<$arr[$insertIndex]){
//把较大的数后移
$arr[$insertIndex+1] = $arr[$insertIndex];
$insertIndex--;
}
//插入(这时为$indexVal找到适当的位置了)
$arr[$insertIndex+1] = $insertVal;
}
return $arr;
}
四:归并排序
1:算法步骤
-
申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列。
-
设定两个指针,最初位置分别为两个已经排序序列的起始位置。
-
比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置。
-
重复步骤 3 直到某一指针达到序列尾。
-
将另一序列剩下的所有元素直接复制到合并序列尾。
2:动态演示
3:示例代码
/**
* 归并排序
*/
public function mergeSort($arr)
{
$len = count($arr);
//数组就只有一个元素时,直接返回
if ($len <= 1) {
return $arr;
}
$mid = intval($len / 2); // 取数组中间
$left = array_slice($arr, 0, $mid); //数组拆分,以0下标开始,长度为$mid拆分
$right = array_slice($arr, $mid); // 数组拆分,以$mid下标开始到数组结尾拆分
$left = $this->mergeSort($left); // 左边拆分完后开始递归合并往上走
$right = $this->mergeSort($right); // 右边拆分完毕开始递归往上走
$arr = $this->merge($left, $right);
return $arr;
}
/**
* 将指定的两个有序数组(arrA, arr)合并并且排序
*/
public function merge($arrA, $arrB)
{
$arrC = array();
while (count($arrA) && count($arrB)) {
// 这里不断的判断哪个值小, 就将小的值给到arrC, 但是到最后肯定要剩下几个值,
// 不是剩下arrA里面的就是剩下arrB里面的而且这几个有序的值, 肯定比arrC里面所有的值都大所以使用
$arrC[] = $arrA[0] < $arrB[0] ? array_shift($arrA) : array_shift($arrB);//array_shift():删除数组中第一个元素,并返回被删除元素的值
}
return array_merge($arrC, $arrA, $arrB);
}
五:快速排序
1:算法步骤
-
从数列中挑出一个元素,称为 “基准”(pivot)。
-
重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
-
递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
2:动态演示
3:示例代码
/**
* 快速排序
*/
public function quickSort($arr)
{
//判断传入的数组是否只有一个,只有一个不需要进行排序,直接返回
if (count($arr) <= 1) {
return $arr;
}
$middle = $arr[0]; // 设置中间值
$left = array(); // 接收小于中间值
$right = array();// 接收大于中间值
// 循环比较
for ($i=1; $i < count($arr); $i++) {
if ($middle < $arr[$i]) {
// 大于中间值
$right[] = $arr[$i];
} else {
// 小于中间值
$left[] = $arr[$i];
}
}
// 递归排序划分好的2边
$left = $this->quickSort($left);
$right = $this->quickSort($right);
// 合并排序后的数据
return array_merge($left, array($middle), $right);
}