php 十大排序算法

<?php
#它的基本思想是: 首先在未排序的数列中找到最小(or最大)元素,
#然后将其存放到数列的起始位置;接着,再从剩余未排序的元素中继续寻找最小(or最大)元素,
#然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕
$arr  =[1,9,20,2,3,14,8,11,7];
function SelectSort($arr) {
   for ($i=0;$i<count($arr)-1;$i++) {
       $min = $i;
       for($j=$i+1;$j<count($arr);$j++) {
          if ($arr[$min]>$arr[$j]) {
              $min = $j;
          }
       }
       if ($i!=$min) {
           $temp      = $arr[$i];
           $arr[$i]   = $arr[$min];
           $arr[$min] = $temp;
       }
   }
   return $arr;
}
$data  = SelectSort($arr);
#直接插入排序(Straight Insertion Sort)的基本思想是: 
#把n个待排序的元素看成为一个有序表和一个无序表。
#开始时有序表中只包含1个元素,无序表中包含有n-1个元素,
#排序过程中每次从无序表中取出第一个元素,将它插入到有序表中的适当位置,
#使之成为新的有序表,重复n-1次可完成排序过程
function InsertSort($arr) {
    $current = 0;
    $index   = 0;
    for ($i=1;$i<count($arr);$i++) {
          $index   = $i-1;
          $current = $arr[$i];
          while($index>=0 && $current<$arr[$index]) {
              $arr[$index+1] = $arr[$index];
              $index --;
          }
          $arr[$index+1] = $current;
    }
    return $arr;
}
$data  = InsertSort($arr);

#冒泡排序是一种简单的排序算法,它也是一种稳定排序算法。
#其实现原理是重复扫描待排序序列,并比较每一对相邻的元素,
#当该对元素顺序不正确时进行交换。一直重复这个过程,
#直到没有任何两个相邻元素可以交换,就表明完成了排序。注意每次找到最大的沉底
#例如 [1,3,8,2] 第一次找到8沉底,第二次只需要遍历 1 3 2 两两交换
function BubbleSort($arr) {
    for ($i=0;$i<count($arr);$i++) {
          for ($j=0;$j<count($arr)-$i-1;$j++) {
              if ($arr[$j]>$arr[$j+1]) {
                  $temp = $arr[$j];
                  $arr[$j] = $arr[$j+1];
                  $arr[$j+1] = $temp;
              }
          }
    }
    return $arr;
}
# 快速排序选择一个基准数,通过一趟排序将要排序的数据分割成独立的两部分;
#其中一部分的所有数据都比另外一部分的所有数据都要小。
#然后,再按此方法对这两部分数据分别进行快速排序,
#整个排序过程可以递归进行,以此达到整个数据变成有序序列
function QuickSort(&$arr,$low,$high) {
        if($low>$high){
            return;
        }
        $i=$low;
        $j=$high;
        //temp就是基准位
        $temp = $arr[$low];
        while ($i<$j) {
            //先看右边,依次往左递减
            while ($temp<=$arr[$j]&&$i<$j) {
                $j--;
            }
            //再看左边,依次往右递增
           while ($temp>=$arr[$i]&&$i<$j) {
                $i++;
            }
            //如果满足条件则交换
            if ($i<$j) {
                $t = $arr[$j];
                $arr[$j] = $arr[$i];
                $arr[$i] = $t;
            }
        }
        //最后将基准为与i和j相等位置的数字交换
         $arr[$low] = $arr[$i];
         $arr[$i] = $temp;
        //递归调用左半数组
        QuickSort($arr, $low, $j-1);
        //递归调用右半数组
        QuickSort($arr, $j+1, $high);
}
function quickSort2($arr) {
    if (count($arr)<=1) {
        return $arr;
    }
    $middle = array_pop($arr);
    $left =[];
    $right=[];
    for ($i=0;$i<count($arr);$i++) {
        if ($middle>$arr[$i]) {
             $left[]  = $arr[$i];
        } else {
             $right[] = $arr[$i];
        }
    }
  return  array_merge(quickSort2($left),[$middle],quickSort2($right));
}

//二分查找
function BinarySearch($arr,$low,$high,$number) {
     while($low<=$high) {
         $mid = intval(($low+$high)/2);
         if ($arr[$mid]<$number) {
             $low = $mid +1;
         } else if($arr[$mid]>$number) {
             $high = $mid-1;
         } else {
             return $mid;
         }
     }
     return -1;
}
//推排序
function heapSort($arr) {
  $max =0;
  for ($i=0;$i<count($arr);$i++) {
       if ($arr[$i]>$max) {
           $max = $arr[$i];
       }
  }
  $heap =[];
  $arrNumber =[];
  for ($i=0;$i<=$max;$i++) {
      $heap[$i] =[];
      $arrNumber[$i] =0;
  }
  for ($i=0;$i<count($arr);$i++) {
      $heap[$arr[$i]][] = $arr[$i];
      $arrNumber[$arr[$i]]++;
  }
  $index = 0;
  for ($j=0;$j<count($heap);$j++) {
      if (!empty($heap[$j])) {
          for ($k=0;$k<count($heap[$j]);$k++) {
              if ($arrNumber[$heap[$j][$k]]!=0) {
                  $arr[$index] = $heap[$j][$k];
                  $index++;
              }
          }
      }
  }
  return $arr;
}
#归并排序包括"从上往下"和"从下往上"2种方式。
#从下往上的归并排序:将待排序的数列分成若干个长度为1的子数列,
#然后将这些数列两两合并;得到若干个长度为2的有序数列,再将这些数列两两合并;
#得到若干个长度为4的有#序数列,再将它们两两合并;直接合并成一个数列为止。
#这样就得到了我们想要的排序结果
#上往下的归并排序:与"从下往上"在排序上是反方向的
function mergeSort($arr) {
    if (count($arr)<2) {
        return $arr;
    }
   $num   =  floor(count($arr)/2);
   $left  = array_slice($arr,0,$num);
   $right = array_slice($arr,$num,count($arr));
  return merge(mergeSort($left),mergeSort($right));
}
function merge($left,$right) {
  $result =[];
  while(count($left)>0 && count($right)>0) {
      if ($left[0]<=$right[0]) {
          $result[] = array_shift($left);
      } else {
          $result[] = array_shift($right);
      }
  }
  while (count($left)) {
        $result[] = array_shift($left);
  }
  while (count($right)) {
        $result[] = array_shift($right);
  }
  return $result;
}
#希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本。
#但希尔排序是非稳定排序算法。
#希尔排序是基于插入排序的以下两点性质而提出改进方法的:
#插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率;
#但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位;
#希尔排序的基本思想是:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,
#待整个序列中的记录"基本有序"时,再对全体记录进行依次直接插入排序。
function shell($arr) {
    $len = count($arr);
    $gap = ceil($len/2);
    $temp = "";
    for ($i=$gap;$i>0;$i=floor($i/2)) {
        for ($j=$i;$j<$len;$j++) {
            $temp = $arr[$j];
            for ($k=$j-$i;$k>0;$k=$k-$i) {
                if ($arr[$k]>$temp) {
                    $arr[$k+$i] = $arr[$k];
                }
            }
            $arr[$k+$i] = $temp;
        }
    }
    return $arr;
}
#计数排序
#计数排序的核心在于将输入的数据值转化为键存储在额外开辟的数组空间中。
#作为一种线性时间复杂度的排序,计数排序要求输入的数据必须是有确定范围的整数。
function countSort($arr,$max=null) {
     if ($max===null) {
         $max = max($arr);
     }
    $bucket =[];
     for ($i=0;$i<=$max;$i++) {
        $bucket[] = null;
     }
     $len = count($arr);
     for ($i=0;$i<$len;$i++) {
         if (!array_key_exists($arr[$i],$bucket)) {
              $bucket[$arr[$i]] = 0;
         } else {
             $bucket[$arr[$i]]++;
         }
     }
     $index = 0;
    foreach ($bucket as $key => $len) {
        if($len !== null){
            for($j = 0; $j < $len; $j++){
                $arr[$index++] = $key;
            }
        }
    }
    return $arr;
}
# 桶排序
# 桶排序是计数排序的升级版。它利用了函数的映射关系,
# 高效与否的关键就在于这个映射函数的确定。为了使桶排序更加高效,我们需要做到这两点:
# 在额外空间充足的情况下,尽量增大桶的数量
# 使用的映射函数能够将输入的 N 个数据均匀的分配到 K 个桶中
function bucketSort($arr,$bucketSize = 5) {
   if (count($arr)===0) {
       return $arr;
   }
   $minValue = $arr[0];
   $maxValue = $arr[0];
   for ($i=1;$i<count($arr);$i++) {
       if ($arr[$i]<$minValue) {
           $minValue = $arr[$i];
       } else if($arr[$i]>$minValue) {
           $maxValue = $arr[$i];
       }
   }
   $bucketCount = ceil(($maxValue-$minValue)/$bucketSize);
   $buckets =[];
   for ($i=0;$i<$bucketCount;$i++) {
       $buckets[$i]=[];
   }
   for ($i=0;$i<count($arr);$i++) {
       $buckets[floor(($arr[$i] - $minValue) / $bucketSize)][] = $arr[$i];
   }
    $arr = array();
    for ($i = 0; $i < count($buckets); $i++) {
        $bucketTmp = $buckets[$i];
        //排序可以用任何排序,插入,冒泡都可以
        sort($bucketTmp);
        for ($j = 0; $j < count($bucketTmp); $j++) {
            $arr[] = $bucketTmp[$j];
        }
    }
    return $arr;
}
#基数排序
#基数排序是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,
#然后按每个位数分别比较。由于整数也可以表达字符串(比如名字或日期)
#和特定格式的浮点数,所以基数排序也不是只能使用于整数
#基数排序 vs 计数排序 vs 桶排序
#这三种排序算法都利用了桶的概念,但对桶的使用方法上有明显差异
#基数排序:根据键值的每位数字来分配桶;
#计数排序:每个桶只存储单一键值
#桶排序:每个桶存储一定范围的数值;
function radixSort() {
    $arr=[125,3,18,76,9,104,25,46,22,97];
    $radix = getRadix($arr);
    $bucket =[];
    $everyBucketNum =[];
    for ($i=0;$i<10;$i++) {
        $bucket[$i]=[];
        $everyBucketNum[$i] = 0;
    }
    $expr = 1;
    for ($i=0;$i<$radix;$i++) {
        for ($j=0;$j<count($arr);$j++) {
            $digit = $arr[$j]/$expr%10;
            $bucket[$digit][] = $arr[$j];
            $everyBucketNum[$digit]++;
        }
        $expr = $expr*10;
        $index = 0;
        for ($k=0;$k<count($everyBucketNum);$k++) {
            if ($everyBucketNum[$k]!=0) {
                for ($l=0;$l<$everyBucketNum[$k];$l++) {
                    $arr[$index] = $bucket[$k][$l];
                    $index++;
                }
            }
            $everyBucketNum[$k] =0;
            $bucket[$k]=[];
        }
    }
    return $arr;
}
function getRadix($arr) {
    $max = 0;
    for ($i=0;$i<count($arr);$i++) {
        if ($arr[$i]>$max) {
            $max = $arr[$i];
        }
    }
    return strlen($max."");
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值