<?php
Function Test() {
static $count = 0; //靜態變量只在首次調用時初始化,並被保持直到腳本運行結束
$count++;
echo $count;
if($count < 10){
Test();
}
$count--;//返回的時候靜態變量清零
}
?>
<?php
//test() 與 test1() 等價
Function Test() {
static $count = 0;
$count++;
echo $count;
if($count < 3){
Test();
}
$count--;
}
Function Test1() {
//------------1 begin---------------
static $count = 0;
$count++;
echo $count; //1
if($count < 3){
//------------2 begin---------------
static $count = 0;
$count++;
echo $count; //2
if($count < 3){
//------------3 begin---------------
static $count = 0;
$count++;
echo $count; //3
if($count < 3){
echo "這里不可能執行.";
}
$count--;
//------------3 end---------------
}
$count--;
//------------2 end---------------
}
$count--;
//------------1 end---------------
}
?>
--------------------------------------遞歸說明----------------------------------------
1.遞歸函數調用其實和普通的函數調用沒什么區別,只不過每次call的是同一個函數而已。
2.遞歸的本質。遞歸是一段程序的代碼反復效用,把程序的參數等變量保存在一個堆棧里,直到到了邊界條件以后再層層返回,將堆棧中的數據彈出計算,最后得到結果
3.遞歸需要系統堆棧,所以空間消耗要比非遞歸代碼要大很多,而且,如果遞歸深度太大,可能系統資源會不夠用。
4.理論上,遞歸和循環是等價的。
所有的遞歸都可以轉化為循環,所有的循環都可以轉化為遞歸。
其實,求值遞歸的意義不大。
遞歸求值最終都可以用數據歸納法總結出來一個終極公式。連循環形式都不用,一個公式直接出結果。
遞歸和循環之間的橋接器是尾遞歸。
我們知道,循環 = 尾遞歸
所有的遞歸都可以轉化成尾遞歸(即循環),區別在於轉化的代價是多大,好處是多大。
遞歸的形式有兩種,線性遞歸和樹型遞歸。
線性遞歸就是函數只調用自己一次。樹型遞歸則是函數調用自己多次。比如樓主的例子,就是樹型遞歸。
不過,樹型遞歸都是可以線性化的,畢竟,運行棧本身就是線性的(一個數組)。
這要看后面的循環步驟(或者下面層次的遞歸)需要多少層前面的結果。這個層數就是遞歸轉化為循環(尾遞歸)的代價。比如,樓主的例子,層數就是 3。這時候,轉化為循環,就是值得的。
在極端情況下,循環步驟(或者下面層次的遞歸)需要前面所有層的結果,這個時候,遞歸轉化為循環,就毫無意義。
這通常是遍歷的情況。比如,樹結構的深度優先遍歷。這時候,循環和遞歸沒有什么區別。循環的形式還更難看,還需要自己維護一個不斷伸縮的運行棧。