2009-04-17 161 views
1

我有這樣的功能,其基本操作簡述如下:優化非尾遞歸函數

function render($index) { 
    foreach($things[$index] as $key => $data) { 
     echo '<div>'; 
     /* irrelevant operations */ 
     if(isset($data['id'])) { 
      echo '<div class="wrap">'; 
      render($things[$data['id']]); 
      echo '</div>'; 
     } 
     echo '</div>'; 
    } 
} 

我不能爲我的生活弄清楚如何優化這個功能;我擔心如果調用堆棧變得太大,PHP會崩潰。

有什麼辦法可以優化這個功能嗎?

+0

我很困惑。所以你打印出的所有東西都是嵌套的div?或者你是否放棄了部分功能?無論哪種方式,這看起來都非常適合我。我沒有看到你想要完成的任何捷徑。 – 2009-04-17 23:48:22

回答

3

此代碼是未經測試,但是從我的頭頂,迭代函數應該是這個樣子:

function render($index){ 
    $stack = array(); 
    array_push($index); 

    $pre = ''; 
    $post = ''; 

    while(!empty($stack)){ 
     $idx = array_pop($stack); 

     foreach($things[$idx] as $key => $value){ 
      $pre .= '<1>'; 
      $spost = ''; 

      if(isset($data['id'])){ 
       $pre .= '<2 class="wrap">'; 
       $spost .= '</2>'; 

       $stack[] = $things[$data['id']]; 
      } 

      $spost .= '</1>'; 
      $post .= $spost; 
     } 
    } 

    return $pre . $post; 
} 
3

你在做什麼實際上是遍歷一棵樹。基本上,這不僅僅是將所有值都打印在樹中。你是否遇到過這麼大的麻煩?這棵樹有多深嵌套?

9

這是非常值得懷疑,你必須擔心。如果你足夠深的嵌套深度以致調用堆棧填滿,遞歸深度是你最擔心的問題。

3

您不需要使用遞歸來對樹進行深度優先遍歷;它恰好運作得非常好。如果吹你的堆棧是一個問題,你可以只持有最後和當前位置的所有元素運行一個長循環。遞歸是一種更簡單,並且(通常)更好的方式來執行深度優先遍歷。