多种排序算法(php实现)

1.冒泡排序算法  

function maopaosort($data){

 for ($i = 0; $i < count($data); $i++) {

  //对待排序序列进行冒泡排序

  //相邻两个数比较,将最大的放到最后面,下一轮循环就不需要循环最后一个最大的数据
  for ($j = 0; $j + 1 < count($data) - $i; $j++) {
  //相邻元素进行比较,当顺序不正确时,交换位置
    if ($data[$j] > $data[$j + 1]) {
      $tmp = $data[$j];
      $data[$j] = $data[$j + 1];
      $data[$j + 1] = $tmp;
    }
  }
 } 

 return $data; 

//与第一种相反

function maopaosort($data){  

  //$data = ['9','4','8','6','5','3',];

  //获取data的长度
  $len = count($data);

  //与上面相反,将最小的放到最前面,下一次循环的时候跳过最小的一个
  for($i=0;$i<$len;$i++){

    //索引从大的向小的方向,筛选最小的放到最前面
    for($j=$len-1;$j-1 >= $i;$j--){
      if($data[$j] < $data[$j-1]){
        $tmp = $data[$j];
        $data[$j] = $data[$j-1];
        $data[$j-1] = $tmp;
      }
    }
  }

//这个和第一种类似

function maopaosort($data){

  $len = count($data);
  for ($i = $len-1; $i > 0 ; $i--) {
  //索引从小的向大的方向,筛选最大的放到最后面,下次循环跳过最大的数值

    for ($j = 0; $j + 1 <= $i; $j++) {
    //相邻元素进行比较,当顺序不正确时,交换位置
      if ($data[$j] > $data[$j + 1]) {
        $tmp = $data[$j];
        $data[$j] = $data[$j + 1];
        $data[$j + 1] = $tmp;
      }
    }
  }

  return $data;

}

 2选择排序算法

  

function ChoiceSort($arr){ 

  //大循环,控制轮数   

  for ($i=0; $i < count($arr); $i++) {
  //定义一个索引锁定为最小值,即为最小值索引
    $k = $i;
    //从后面的索引里面找到最小的值
    for ($j=$i+1; $j < count($arr); $j++) {
      if ($arr[$k] > $arr[$j]) {
        //如果当前索引的值比后面索引的值大,更换索引
        $k = $j;
      }
    }
  //如果索引与最初索引不同,说明最小值已变化,原先的最小索引已变化,最小值另有其值,
  //更换最小值与第一个值 ,即将最小值放在第一个位置,之后继续下一次循环
    if ($k != $i) {
      $tmp = $arr[$i];
      $arr[$i] = $arr[$k];
      $arr[$k] = $tmp;
    }
  }

  return $arr;

 3 插入排序算法

  

function insert($arr){
  //插入排序
  $arr = array(4,2,6,8,9,5);
  //1 确定要插入多少回,(假设一个数组一次性插入到对的位置,同时第一个位置假设是对的)
  $len=count($arr);
  for($i=1;$i<$len;$i++){
    //2 取出当前要插入的元素的值
    $temp = $arr[$i];
    //标记:默认说明当前要插入的数组的位置是对的
    $change = false;
    //3 让该数据与前面已经排好序的数组元素重复比较(挨个比较),直到要交换的位置
    for($j = $i-1;$j >= 0;$j--){
      //4 比较
      if($arr[$j] > $temp){
      //说明当前要插入的元素,比前面已经排好序的元素的值要小:交换位置
      $arr[$j+1] = $arr[$j];
      //$arr[$j] = $temp;
      //说明前面顺序的数组元素有不合适的位置
      $change = true;
    }else{
      //说明当前待插入元素比前面的元素要大,说明位置正确
      break;
    }
  } 
    //判断位置需要变动,
    if($change){
    //有数据移动,站错位置了
      $arr[$j+1] = $temp; 
    }
  }

 4 归并排序算法

  

<?php 
  $arr1 = array(1,3,5);
  $arr2 = array(2,4,6);
  $arr3 = array();
  dump(array_merge($arr3,$arr2,$arr1));
  print_r(merge_sort(array_merge($arr3,$arr2,$arr1)));


  function merge_sort($arr){
    //递归出口
    $len = count($arr);
    if($len <= 1)
      return $arr;
    //拆分
    $middle = floor($len/2);
    $left = array_slice($arr,0,$middle);
    $right = array_slice($arr,$middle);
    //递归点:$left和$right都没有排好序,而且可能是多个元素的数组
    $left = merge_sort($left);
    $right = merge_sort($right);

    //假设左边和右边已经排好序,二路归并
    $m = array();
    while (count($left) && count($right)) {
      //只要$arr1和$arr2里面还有元素,就进行循环,取出每个数组的第一个元素:进行比较
      $m[] = $left[0] < $right[0]?array_shift($left):array_shift($right);
     } 
    //返回结果
    return array_merge($m,$left,$right); 
  } 
?> 

 5 顺序查找算法

  

 

  //查找算法,顺序查找

  //$arr = array(1,3,6,8,23,45,68,100);
  function check_order($arr,$num){
  //全部匹配
  /* $len = count($arr);
  for($i = 0;$i<$len;$i++){
  //判断
  if($arr[$i] == $num){
    return $i;
    }
  }
  return false; */ 
 }

 6 二分查找算法

   

 

   

  $arr = array(1,3,6,8,23,45,68,100);
  $res = 100;
  var_dump(check_break($arr,$res));
  (int)$i = check_break($arr,$res);
  dd($i,$arr[$i-1]);
  function check_break($arr,$res){
    //二分查找算法
    //1 得到数组边界
    $right = count($arr);
    $left = 0; 
    //2 循环匹配
    while ($left <= $right) {
      $middle = floor(($right+$left)/2);
      if($arr[$middle] == $res){
      return $middle+1;
    } 
    if($arr[$middle] < $res){
      $left = $middle+1;
    }else{
      $right = $middle -1;
    } 
  }
  return false; 
}

7快速排序算法

  

 <?php 

  $arr = ['6','4','2','5','3','9','7'];

  print_r(quick_sort($arr));
  //快速排序 ,原理:以第一个为基准数,第一轮从最后向前走,若数据比基准数小,则将数值放到基准数的位置,再从前面往后走,若数据比基准数大,则将数值放到后面基准数的位置,以此类推,直到索引相等或大于,找到基准数的位置,后面的轮循以此类推。
  function quick_sort($arr){
    //递归出口
    $len = count($arr);
    if($len <= 1)
      return $arr;
    //取出某个元素,然后将剩余的数组元素分散到两个不同的数组中
    $left = $right = array();
    for($i = 1;$i < $len;$i++){
      //第一个元素作为比较元素
      //比较:小的放left中,大的放right中
      if($arr[$i] < $arr[0]){
        $left[] = $arr[$i]; 
      }else{
        $right[] = $arr[$i];
      }
    }
    //$left和$right 数组元素没有排好序,递归点 
    $left = quick_sort($left); 
    $right = quick_sort($right); 
    //合并三个数组
    return array_merge($left,(array)$arr[0],$right);

  } 

?>

8. 微信红包的随机算法 

  

 function randBonus($bonus_total=0, $bonus_count=3, $bonus_type=1){

  // $bonus_total 红包总金额
  // $bonus_count 红包个数
  // $bonus_type 红包类型 1=拼手气红包 0=普通红包
  // 将要瓜分的结果
  $bonus_items = array(); 
  // 每次分完之后的余额
  $bonus_balance = $bonus_total; 
  //dd($bonus_balance);
  // 平均每个红包多少钱
  $bonus_avg = number_format($bonus_total/$bonus_count, 2); 
  $i = 0;
  while($i<$bonus_count){
  if($i<$bonus_count-1){
    // 根据红包类型计算当前红包的金额
    $r = mt_rand(0.01, $bonus_balance*100-1)/100; 
    $rand = $bonus_type?$r:$bonus_avg; 
    $bonus_items[] = $rand;
    $bonus_balance -= $rand; 
    dump($bonus_items);
    echo $bonus_balance.'-------'; 
    echo PHP_EOL;
  }else{
  // 最后一个红包直接承包最后所有的金额,保证发出的总金额正确
    $bonus_items[] = $bonus_balance; 
  } 
    $i++;
  }
  return $bonus_items;
}

 

  

posted @ 2020-09-03 11:13  u-ttXY  阅读(202)  评论(0编辑  收藏  举报