= 0;$j--){
//$arr[$i] 需要插入的元素
//$arr[$j] 需要比较的元素
//监视哨的值 比 查找的值小 并且 没有到此次查询的第一个
if($tmp < $arr[$j]){
//发现插入的元素要小,交换位置
//将后边的元素与前面的元素交换
$arr[$j+1] = $arr[$j];
}else{
//碰到不需要移动的元素
//由于是已经排好的数组,则前面的就不需要再次比较了
break;
}
}
//插入
$arr[$j+1] = $tmp;
}
return $arr;
}
$arr = [3,2,42,56,8,2];
$arr2 = insertSort($arr,count($arr));
print_r($arr2);
/*
* 希尔排序
* 基本思想:先将整个待排的序列分割成若干序列分别进行直接插入排序,待整个序列中的记录基本有序时,再对全体记录进行依次直接排序
* 实质是分组插入排序
* 操作方法:
* 1.选择1个增量序列,t1,t2,t3,t4,...,tk,其中ti>tj,tk=1
* 2.按增量序列个数k,对序列进行k趟排序
* 3.每趟排序,根据对应的增量ti,将待排序列分割成若干长度为m的子序列,分别对各子序列进行直接插入排序,仅增量因子为1时,整个序列作为1个
* 表来处理,表长度即为整个序列的长度
*
*/
function shell_sort(array $arr){
// 将$arr按升序排列
$len = count($arr);
$f = 4;// 定义因子
$h = 1;// 最小为1
while ($h < $len/$f){
$h = $f*$h + 1; // 1, 4, 13, 40, 121, 364, 1093, ...
}
while ($h >= 1){ // 将数组变为h有序
for ($i = $h; $i < $len; $i++){ // 将a[i]插入到a[i-h], a[i-2*h], a[i-3*h]... 之中 (算法的关键
for ($j = $i; $j >= $h; $j -= $h){
if ($arr[$j] < $arr[$j-$h]){
$temp = $arr[$j];
$arr[$j] = $arr[$j-$h];
$arr[$j-$h] = $temp;
}
//print_r($arr);echo '
'; // 打开这行注释,可以看到每一步被替换的情形
}
}
$h = intval($h/$f);
}
return $arr;
}
function shellSort3($arr)
{
//计算长度
$n = count($arr);
//计算增量
for ($gap = floor($n / 2); $gap > 0; $gap = floor($gap / 2)) { //步长
//分组 第一次5组 第二次2组 第三次1组
for ($i = 0; $i < $gap; $i++)
{
//分组之后的数据,每组内部进行直接插入排序
for ($j = $i + $gap; $j < $n; $j += $gap)
{
$tmp = $arr[$j];
for ($k = $j - $gap;$k >= 0 && $arr[$k] > $tmp;$k -= $gap)
{
$arr[$k + $gap] = $arr[$k];
}
$arr[$k + $gap] = $tmp;
}
}
}
return $arr;
}
$arr = array(14, 29, 1, 4, 6, 2,1);
$shell = shellSort3($arr);
print_r($shell);
/*
* 选择排序
* 要点:在要排序的一组数中,选出最小或者最大的一个数与第一个位置的数交换,然后在剩下的数当中再找最小的与第二个位置的数交换,
* 直到第n-1个元素和第n个元素比较为止
*
*/
function selectSort($arr) {
//实现思路 双重循环完成,外层控制轮数,当前的最小值。内层 控制的比较次数
//$i 当前最小值的位置, 需要参与比较的元素
for($i=0, $len=count($arr); $i<$len-1; $i++) {
//先假设最小的值的位置
$p = $i;
//$j 当前都需要和哪些元素比较,$i 后边的。
for($j=$i+1; $j<$len; $j++) {
//$arr[$p] 是 当前已知的最小值
if($arr[$j]<$arr[$p]) {
//比较,发现更小的,记录下最小值的位置;并且在下次比较时,
// 应该采用已知的最小值进行比较。
$p = $j;
}
}
//已经确定了当前的最小值的位置,保存到$p中。
//如果发现 最小值的位置与当前假设的位置$i不同,则位置互换即可
if($p != $i) {
$tmp = $arr[$p];
$arr[$p] = $arr[$i];
$arr[$i] = $tmp;
}
}
//返回最终结果
return $arr;
}
$arr = array(14, 29, 1, 4, 6, 2,1);
$arr2 = selectSort($arr);
print_r($arr2);
/*
* 二元选择排序 这个有问题
* 改进为每趟循环确定两个元素(当前趟最小和最大的记录)的位置,从而减少排序的所需次数。
*/
function selectSort2($arr){
$n = count($arr);
for($i=1;$i$arr[$max])
{
$max = $j;
continue;
}
if($arr[$j]<$arr[$min]){
$min = $j;
}
}
$tmp1 = $arr[$i-1];
$arr[$i-1] = $arr[$min];
$arr[$min] = $tmp1;
$tmp2 = $arr[$n-1];
$arr[$n-$i] = $arr[$max];
$arr[$max] = $tmp2;
}
return $arr;
}
/**
* 冒泡排序
*/
function getPao($arr)
{
$len=count($arr);
//设置一个空数组 用来接收冒出来的泡
//该层循环控制 需要冒泡的轮数
for($i=1;$i<$len;$i++)
{ //该层循环用来控制每轮 冒出一个数 需要比较的次数
for($k=0;$k<$len-$i;$k++)
{
if($arr[$k]>$arr[$k+1])
{
$tmp=$arr[$k+1];
$arr[$k+1]=$arr[$k];
$arr[$k]=$tmp;
}
}
}
return $arr;
}
/*
* 快速排序 交换排序
* 思想:1.选择一个基准元素,通常选第一个元素或者最后一个元素
* 2.通过1趟排序将待排序的元素
*/
// 寻找分割点,并交换值
function slicearr(&$arr, $low, $high)
{
$i = $low;
$j = $high + 1;
$choosen = $arr[$low];
while (1) {
while ($arr[++$i] < $choosen) {// 从左边要找大的,把大的交换到右边去
if ($i >= $high) break;
}
while ($arr[--$j] > $choosen) {// 从右边要找小的,交换到左边去
if ($j <= $low) break;
}
// 从左往右找,或者从右往左找,如果i>j了,表示此处顺序对了,就不替换i,j位置的元素了,break掉
if ($i >= $j) break;
$temp = $arr[$i];
$arr[$i] = $arr[$j];
$arr[$j] = $temp;
}
$temp = $arr[$low];
$arr[$low] = $arr[$j];
$arr[$j] = $temp;
//echo '';print_r($arr); // 查看每次切分后的数组排序情况
//echo $j,'
'; // 查看切分点
return $j;// 返回分割点
}
// 递归快速排序
function qsort(&$arr, $low, $high)
{
if ($low >= $high) return;
$i = slicearr($arr, $low, $high);// 该步骤的分割点
qsort($arr, $low, $i - 1);// 递归调用
qsort($arr, $i + 1, $high);
}
$arr3 = array(10, 292, 13, 24, 6, 2,1);
qsort($arr3,0, count($arr)-1);
print_r($arr3);