【问题标题】:Sorting an array with bubble sort [duplicate]用冒泡排序对数组进行排序[重复]
【发布时间】:2020-05-17 12:10:38
【问题描述】:

我正在尝试创建一种算法来显示冒泡排序的每个步骤,一次排序一个数字。我能够在第一个索引处对数字进行排序,但我需要弄清楚如何对所有数字进行排序。

$x = array (9,7,5,3,0);

$count = count($x);
for($i = 0; $i < $count-1; $i++ ) {
    $temp = $x[$i+1];
    $x[$i+1] = $x[$i];
    $x[$i] = $temp;
    echo '<pre>';
    print_r($x);
}

我目前的输出是:

Array
(
    [0] => 7
    [1] => 9
    [2] => 5
    [3] => 3
    [4] => 0
)
Array
(
    [0] => 7
    [1] => 5
    [2] => 9
    [3] => 3
    [4] => 0
)
Array
(
    [0] => 7
    [1] => 5
    [2] => 3
    [3] => 9
    [4] => 0
)
Array
(
    [0] => 7
    [1] => 5
    [2] => 3
    [3] => 0
    [4] => 9
)

从这里我需要继续对剩余的数字进行排序。对于 7,输出应该是

57390
53790
53970
53907

然后是 3

35079
30579
30759
30795

然后对于 0,它应该对所有 4 行都一样

03570
03579
03579
03579

[分配的问题。][1]

【问题讨论】:

    标签: php algorithm sorting bubble-sort


    【解决方案1】:

    您正在执行无条件位置交换,但您实际上需要检查是否需要移动。

    在 php 中演示冒泡排序的教程不乏其人。一个快速的好方法将我带到这个:https://www.w3resource.com/php-exercises/searching-and-sorting-algorithm/searching-and-sorting-algorithm-exercise-6.php,可以根据您的目的进行修改。

    PHP 现在提供“array destructuring”,这意味着您在交换时不再需要使用临时保持变量。

    代码:(Demo)

    $x = [9,7,5,3,0];
    $count = count($x) - 1;
    for ($pass = 0; $pass < $count; ++$pass) {
        for ($i = 0; $i < $count; ++$i) {
            if ($x[$i] > $x[$i + 1]) {
                [$x[$i + 1], $x[$i]] = [$x[$i], $x[$i + 1]];
            }
            $results[] = implode($x);
        }
        $results[] = "\n";
    }
    echo implode("\n", $results);
    

    【讨论】:

      【解决方案2】:

      冒泡排序基本上被简化为min() + shift(或有时是swap)操作,发生N 次。所以这是一个O(n^2) 算法。

      由于这是出于学习目的,我将尝试尽可能详细。

      function getMin(Array &$array): Int {
          $min = reset($array);
          $minKey = null;
      
          // Find the minimum value
          foreach($array as $k => $n) {
              if ($n < $min) {
                  $min = $n;
                  $minKey = $k;
              }
          }
      
          // remove the minimum value from the array
          $array[$k] = null;
          $array = array_filter($array, function ($v) { return $v !== null; });
      
          return $min;
      }
      
      $array = [9,7,5,3,0];
      
      foreach ($array as $n => $value) {
          // Find the min value in the array from Nth index onward
          $min = getMin($array); // get the smallest value in the array and remove it.
          $sorted[] = $min; // push it on to the new array
      }
      
      var_dump($sorted);
      

      这会给你预期的结果:

      数组(5){ [0]=> 整数(0) [1]=> 整数(3) [2]=> 整数(5) [3]=> 整数(7) [4]=> 整数(9) }

      当然,这不是您想要实现冒泡排序的方式,因为它有点迂回。再次,它是出于教育目的。您可以检查$array,因为它在每一步都被修改,新的$sorted 正在构建。通常,您只需交换最小/最大值并使用相同的数组(跟踪键以重新扫描数组)。

      像这样……

      // Unsorted $array
      $array = [9,7,5,3,0];
      
      // Sort the array
      for ($lastKey = $i = 0, $len = count($array); $i < $len; $i++) {
          // Scan for minimum value
          for ($minKey = $j = $lastKey, $min = $array[$minKey]; $j < $len; $j++) {
              if ($array[$j] < $min) {
                  $minKey = $j;
                  $min = $array[$j];
              }
          }
          // Swap the values
          $swap = $array[$lastKey];
          $array[$lastKey] = $min;
          $array[$minKey] = $swap;
      
          // Update the scan position
          $lastKey++;
      }
      
      var_dump($array); // Gives you [0,3,5,7,9]
      

      【讨论】:

        【解决方案3】:

        两个问题:

        • 您应该只在值顺序不正确时交换值
        • 您需要一个外循环来重复这个内循环,类似于正确的冒泡排序算法。

        您的代码可以如下修改,以便生成所需的输出:

        $x = array (9,7,5,3,0);
        
        $count = count($x) - 1;
        for($times = 0; $times < $count; $times++) {
            for($i = 0; $i < $count; $i++ ) {
                $temp = $x[$i+1];
                if ($temp < $x[$i]) {
                    $x[$i+1] = $x[$i];
                    $x[$i] = $temp;
                }
                echo implode(" ", $x) . "\n";
            }
            echo "\n";
        }
        

        请注意,正确的冒泡排序算法将执行更少的迭代。

        【讨论】:

          猜你喜欢
          • 2017-05-29
          • 2020-07-17
          • 2016-07-25
          • 2018-09-22
          • 2017-01-24
          • 1970-01-01
          • 2018-11-11
          • 2016-02-10
          • 1970-01-01
          相关资源
          最近更新 更多