语言学多了,写的多了,各种框架就会忘记。写了一个for嵌套循环的执行顺序demo有个回忆吧。

echo “1. 基本的双重for循环嵌套:\n”;
for ($i = 1; $i <= 3; $i++) {  //执行1次+执行1次 1 2 3
    echo “外层循环第{$i}次执行:\n”;
    for ($j = 1; $j <= 2; $j++) { // 执行2次+执行2次+执行2次
        echo ”  内层循环第{$j}次执行 (i={$i}, j={$j})\n”;
    }
    echo ”  外层循环第{$i}次执行结束\n\n”;
}

实际执行顺序如下:

  1. 外层循环第1次 ($i = 1):
    • 输出:”外层循环第1次执行:”
    • 内层循环执行2次
      • $j = 1:输出:”内层循环第1次执行 (i=1, j=1)”
      • $j = 2:输出:”内层循环第2次执行 (i=1, j=2)”
    • 输出:”外层循环第1次执行结束”
  2. 外层循环第2次 ($i = 2):
    • 输出:”外层循环第2次执行:”
    • 内层循环再次执行2次
      • $j = 1:输出:”内层循环第1次执行 (i=2, j=1)”
      • $j = 2:输出:”内层循环第2次执行 (i=2, j=2)”
    • 输出:”外层循环第2次执行结束”
  3. 外层循环第3次 ($i = 3):
    • 输出:”外层循环第3次执行:”
    • 内层循环再次执行2次
      • $j = 1:输出:”内层循环第1次执行 (i=3, j=1)”
      • $j = 2:输出:”内层循环第2次执行 (i=3, j=2)”
    • 输出:”外层循环第3次执行结束”

总结:

  • 外层循环总共执行 3次$i 从 1 到 3)
  • 每次外层循环都会完整执行内层循环 2次$j 从 1 到 2)
  • 因此,内层循环总共执行 3 × 2 = 6次

嵌套循环的关键原则是:外层循环每执行一次,内层循环都要完整执行一轮

//=================================================

echo “2. 三重for循环嵌套演示:\n”;
$count = 1;
for ($a = 1; $a <= 2; $a++) { // 执行1次 中间层执行完整 1 2
    echo “最外层循环 a={$a}:\n”;
    for ($b = 1; $b <= 2; $b++) { // 2次
        echo ”  中间层循环 b={$b}:\n”;
        for ($c = 1; $c <= 2; $c++) { //
            echo ”    最内层循环 c={$c} (执行顺序: {$count})\n”;
            $count++;
        }
    }
}
echo “\n”;

执行顺序详解:

第一轮:$a = 1

  1. 最外层循环第1次 ($a = 1)
    • 输出:”最外层循环 a=1:”
    1. 中间层循环第1次 ($b = 1)
      • 输出:” 中间层循环 b=1:”
      1. 最内层循环执行2次
        • $c = 1:输出:” 最内层循环 c=1 (执行顺序: 1)”,$count 变为 2
        • $c = 2:输出:” 最内层循环 c=2 (执行顺序: 2)”,$count 变为 3
    2. 中间层循环第2次 ($b = 2)
      • 输出:” 中间层循环 b=2:”
      1. 最内层循环再次执行2次
        • $c = 1:输出:” 最内层循环 c=1 (执行顺序: 3)”,$count 变为 4
        • $c = 2:输出:” 最内层循环 c=2 (执行顺序: 4)”,$count 变为 5

第二轮:$a = 2

  1. 最外层循环第2次 ($a = 2)
    • 输出:”最外层循环 a=2:”
    1. 中间层循环第1次 ($b = 1)
      • 输出:” 中间层循环 b=1:”
      1. 最内层循环执行2次
        • $c = 1:输出:” 最内层循环 c=1 (执行顺序: 5)”,$count 变为 6
        • $c = 2:输出:” 最内层循环 c=2 (执行顺序: 6)”,$count 变为 7
    2. 中间层循环第2次 ($b = 2)
      • 输出:” 中间层循环 b=2:”
      1. 最内层循环再次执行2次
        • $c = 1:输出:” 最内层循环 c=1 (执行顺序: 7)”,$count 变为 8
        • $c = 2:输出:” 最内层循环 c=2 (执行顺序: 8)”,$count 变为 9

总结

  • 最外层循环执行 2 次 ($a 从 1 到 2)
  • 每次中间层循环执行 2 次 ($b 从 1 到 2)
  • 每次最内层循环执行 2 次 ($c 从 1 到 2)
  • 总共执行次数:2 × 2 × 2 = 8 次最内层循环
  • $count 值的变化:从 1 递增到 8

嵌套循环的执行原则是:最内层循环必须完整执行完毕后,才会返回到外层循环继续执行下一次迭代

//=================================================

echo “3. 希尔排序中的嵌套循环结构演示:\n”;
$arr = [5, 2, 8, 1];
$gaps = [3, 1];
echo “原始数组: ” . implode(‘, ‘, $arr) . “\n”;
foreach ($gaps as $gap) {
    echo “增量={$gap}时的排序过程:\n”;
    for ($i = $gap; $i < count($arr); $i++) {
        $temp = $arr[$i];
        echo ”  处理元素 arr[{$i}]={$temp}:\n”;
        $j = $i;
        while ($j >= $gap && $arr[$j – $gap] > $temp) {
            $arr[$j] = $arr[$j – $gap];
            echo ”    将 arr[” . ($j – $gap) . “]={$arr[$j -$gap]} 移动到位置 {$j}\n”;
            $j -= $gap;
        }
        $arr[$j] = $temp;
        echo ”  元素{$temp}插入到位置{$j}\n”;
        echo ”  当前数组: ” . implode(‘, ‘, $arr) . “\n”;
    }
    echo “\n”;
}

初始状态

  • $arr = [5, 2, 8, 1] (索引为 0, 1, 2, 3)
  • $gaps = [3, 1]

执行顺序详解

第一轮:$gap = 3

  1. 输出:”增量=3时的排序过程:”
  2. for循环 ($i = 3$i < 4$i++)
    • 因为 $gap = 3,所以 $i 从 3 开始
    • 数组长度为 4,所以 $i < 4
    • 只执行一次,即 $i = 3
  3. 当 $i = 3 时
    • $temp = $arr[3] = 1
    • 输出:” 处理元素 arr[3]=1:”
    • $j = 3
    1. while循环检查
      • 条件1:$j >= $gap → 3 >= 3 → true
      • 条件2:$arr[$j - $gap] > $temp → $arr[3 - 3] > 1 → $arr[0] > 1 → 5 > 1 → true
      • 两个条件都为真,进入while循环
    2. while循环执行
      • $arr[3] = $arr[0] → $arr[3] = 5
      • 输出:” 将 arr[0]=5 移动到位置 3″
      • $j = 3 - 3 = 0
      • 此时数组变为:[5, 2, 8, 5]
    3. while循环再次检查
      • 条件1:$j >= $gap → 0 >= 3 → false
      • 条件不成立,退出while循环
    4. 插入元素
      • $arr[0] = $temp → $arr[0] = 1
      • 输出:” 元素1插入到位置0″
      • 输出:” 当前数组: 1, 2, 8, 5″
      • 此时数组变为:[1, 2, 8, 5]

第二轮:$gap = 1

  1. 输出:”增量=1时的排序过程:”
  2. for循环 ($i = 1$i < 4$i++)
    • 因为 $gap = 1,所以 $i 从 1 开始
    • 将执行3次:$i = 1$i = 2$i = 3
  3. 当 $i = 1 时
    • $temp = $arr[1] = 2
    • 输出:” 处理元素 arr[1]=2:”
    • $j = 1
    1. while循环检查
      • 条件1:$j >= $gap → 1 >= 1 → true
      • 条件2:$arr[$j - $gap] > $temp → $arr[1 - 1] > 2 → $arr[0] > 2 → 1 > 2 → false
      • 第二个条件为假,不进入while循环
    2. 插入元素
      • $arr[1] = $temp → $arr[1] = 2 (无变化)
      • 输出:” 元素2插入到位置1″
      • 输出:” 当前数组: 1, 2, 8, 5″
  4. 当 $i = 2 时
    • $temp = $arr[2] = 8
    • 输出:” 处理元素 arr[2]=8:”
    • $j = 2
    1. while循环检查
      • 条件1:$j >= $gap → 2 >= 1 → true
      • 条件2:$arr[$j - $gap] > $temp → $arr[2 - 1] > 8 → $arr[1] > 8 → 2 > 8 → false
      • 第二个条件为假,不进入while循环
    2. 插入元素
      • $arr[2] = $temp → $arr[2] = 8 (无变化)
      • 输出:” 元素8插入到位置2″
      • 输出:” 当前数组: 1, 2, 8, 5″
  5. 当 $i = 3 时
    • $temp = $arr[3] = 5
    • 输出:” 处理元素 arr[3]=5:”
    • $j = 3
    1. while循环检查
      • 条件1:$j >= $gap → 3 >= 1 → true
      • 条件2:$arr[$j - $gap] > $temp → $arr[3 - 1] > 5 → $arr[2] > 5 → 8 > 5 → true
      • 两个条件都为真,进入while循环
    2. while循环执行
      • $arr[3] = $arr[2] → $arr[3] = 8
      • 输出:” 将 arr[2]=8 移动到位置 3″
      • $j = 3 - 1 = 2
      • 此时数组变为:[1, 2, 8, 8]
    3. while循环再次检查
      • 条件1:$j >= $gap → 2 >= 1 → true
      • 条件2:$arr[$j - $gap] > $temp → $arr[2 - 1] > 5 → $arr[1] > 5 → 2 > 5 → false
      • 第二个条件为假,退出while循环
    4. 插入元素
      • $arr[2] = $temp → $arr[2] = 5
      • 输出:” 元素5插入到位置2″
      • 输出:” 当前数组: 1, 2, 5, 8″
      • 此时数组变为:[1, 2, 5, 8]

总结

  • 外层foreach循环执行2次
    1. $gap = 3 时:处理数组中以间隔3分组的元素
    2. $gap = 1 时:处理数组中以间隔1分组的元素(即相邻元素)
  • 内层for循环执行情况
    1. 当 $gap = 3 时执行1次 (处理索引3的元素)
    2. 当 $gap = 1 时执行3次 (处理索引1,2,3的元素)
  • while循环:根据元素大小关系决定是否需要在组内移动元素
  • 最终结果:数组从 [5, 2, 8, 1] 变为 [1, 2, 5, 8],完成排序

//=================================================

分类:

发表评论

邮箱地址不会被公开。