排序演算法

卡爾西法發表於2020-02-08
  • 氣泡排序

    /**
    * 氣泡排序
    *
    * @params $arr 要排序的陣列
    * @params $sot 預設升序排序,false 降序排序
    */
      function bubble_sort($arr,$sot = true)
      {
          $len = count($arr);
          for($i=0;$i<$len-1;$i++){
              //用來判斷是否發生交換,沒有則可以結束排序
              $flag = false;
              $mid = null;
              for($j=0;$j<$len-$i-1;$j++){
                  if($sot){
                      //升序排序
                      if($arr[$j]>$arr[$j+1]){
                          $mid = $arr[$j];
                          $arr[$j] = $arr[$j+1];
                          $arr[$j+1] = $mid;
                          $flag = true;
                      }
                  }else{
                      //降序排序
                      if($arr[$j]<$arr[$j+1]){
                          $mid = $arr[$j];
                          $arr[$j] = $arr[$j+1];
                          $arr[$j+1] = $mid;
                          $flag = true;
                      }
                  }
              }
              if(!$flag){
                  //排序已完成
                  break;
              }
          }
          return $arr;
      }
  • 插入排序

       /**
       * 插入排序
       *
       * @params $arr 要排序的陣列
       * @params $flag 預設升序排序 false時,降序排序
       */
      function insertSort($arr,$flag = true)
      {
          $len = count($arr);
    
          for($i = 0;$i<$len-1;$i++){
              $preIndex = $i; //記錄位置
              $current = $arr[$preIndex+1];//記錄下一個的值
    
              while($preIndex >=0){
                  if($flag){
                      if(($current > $arr[$preIndex])){
                          break;
                      }
                  }else{
                      if($current < $arr[$preIndex]){
                          break;
                      }
                  }
                  $arr[$preIndex+1] = $arr[$preIndex];
                  $preIndex--;
              }
              $arr[$preIndex+1] = $current;
          }
          return $arr;
      }
  • 選擇排序

    /**
       * 選擇排序
       *
       * @params $arr 要排序的陣列
       * @params $flag 預設true時,升序排序,否則降序排序
       */
      function select_sort($arr,$flag = true)
      {
          $len = count($arr);
    
          for($i=0;$i<$len;$i++){
              $currentIndex = null;
              $currentIndex = $i; //當前比較元素的位置
              for($j=$i+1;$j<$len;$j++){
                  if($flag ? $arr[$j]<$arr[$currentIndex] : $arr[$j]>$arr[$currentIndex]){
                      $currentIndex = $j;
                  }
              }
              //交換元素
              $mid = null;
              if($i != $currentIndex){
                  $mid = $arr[$i];
                  $arr[$i] = $arr[$currentIndex];
                  $arr[$currentIndex] = $mid;
              }
          }
          return $arr;
      }
  • 希爾排序

    /**
       * 希爾排序
       * @params $arr 排序陣列
       * @params $flag 預設升序排序 false 則降序排序
       */
      function shell_sort($arr,$flag = true)
      {
          $len = count($arr);
          for($gap = floor($len/2);$gap > 0;$gap = floor($gap/2)){
              for($j = $gap;$j < $len;$j++){
                  for($k = $j-$gap;$k >=0 && ($flag ? $arr[$k+$gap] < $arr[$k] : $arr[$k+$gap] > $arr[$k]);$k -= $gap){
                      $temp = $arr[$k];
                      $arr[$k] = $arr[$k+$gap];
                      $arr[$k+$gap] = $temp;
                  }
              }
          }
          return $arr;
      }
  • 二路歸併排序

    $arr = [10, 2, 4, 56, 29, 33, 293, 83, 2, 22];
    function mergeSort(&$arr)
    {
       $left = 0; //第一個元素的下標
       $right = count($arr) -1; //最後一個元素的下標
       divSort($arr,$left,$right);
    }
    function divSort(&$arr,$left,$right)
    {
       if($left < $right) {
       //找出中間索引
       $mid = floor(($left + $right) / 2); //分成兩組
       //對左邊陣列進行遞迴分組
       divSort($arr,$left,$mid);
       //對右邊陣列進行遞迴分組
       divSort($arr,$mid+1,$right);
       //將左右排好順序的陣列進行合併排序
       merge($arr,$left,$mid,$right);
    }
      //將兩個有序陣列合併成一個有序陣列
    function merge(&$arr,$left,$mid,$right)
    {
      $i = $left;
      $j = $mid + 1;
      $temp = []; //臨時合併陣列
    
    while($i <= $mid && $j <= $right)
    {
      if($arr[$i] < $arr[$j]){
          $temp[] = $arr[$i];
          $i++;
      }else{
          $temp[] = $arr[$j];
      $j++;
    }
    }  //比完之後,假如左陣列仍有剩餘,則全部複製到 temp 陣列
    while($i <= $mid) {
       $temp[] = $arr[$i];
       $i++;
    }
    //比完之後,假如右陣列仍有剩餘,則全部複製到 temp 陣列
    while($j <= $right) {
       $temp[] = $arr[$j];
       $j++;
    }
    //將合併序列複製到原始序列中
    for($k = 0; $k < count($temp); $k++) {
       $arr[$left + $k] = $temp[$k];
    }
    }
    //測試
    
    mergeSort($arr);
    var_dump($arr);
  • 快速排序

    function quickSort($arr)
    {
      $len = count($arr);
      if($len < 2) {
          return $arr;
      }
    
      $pivot = $arr[0];   //基準值
      $leftArray = $rightArray = array();
    
      for($i = 1; $i < $len; $i++) {
          if($arr[$i] < $pivot) {
              $leftArray[] = $arr[$i];
          }else{
              $rightArray[] = $arr[$i];
          }
      }
      $leftArray = quickSort($leftArray);
      $rightArray = quickSort($rightArray);
    
      return array_merge($leftArray,array($pivot),$rightArray);
    }
      //測試
      $newArr = quickSort($arr);
      var_dump($newArr);
  • 計數排序

    function countingSort($arr, $maxValue = null)
      {
          if ($maxValue === null) {
              $maxValue = max($arr);
          }
          for ($m = 0; $m < $maxValue + 1; $m++) {
              $bucket[] = null;
          }
          $arrLen = count($arr);
          for ($i = 0; $i < $arrLen; $i++) {
              if (!array_key_exists($arr[$i], $bucket)) {
                  $bucket[$arr[$i]] = 0;
              }
              $bucket[$arr[$i]]++;
          }
          $sortedIndex = 0;
          foreach ($bucket as $key => $len) {
              if ($len !== null){
                  while($len > 0){
                      $arr[$sortedIndex++] = $key;
                      $len--;
                  }
              }
    
          }
    
          return $arr;
      }
      //測試
      $newArr = countingSort($arr);
      var_dump($newArr);
本作品採用《CC 協議》,轉載必須註明作者和本文連結
sunshine

相關文章