三種遍歷樹的方法

2021-09-08 07:26:53 字數 2837 閱讀 1202

樹的概念在開發裡面是很重要的一部分,xml的文件物件模型(dom)就是一棵樹,資料夾檔案的結構也是一棵樹。遍歷樹是開發中經常要遇到的乙個問題,比如,要找出dom裡面的img 標籤的個數,就要遍歷一棵dom樹。要在乙個目錄裡面查詢是否有乙個檔案也要用到遍歷這個目錄。在這裡我們以遍歷檔案為例,說明遍歷樹的三種基本的方法:

遞迴深度優先演算法,非遞迴深度優先演算法,非遞迴廣度優先演算法。

這些演算法是我們在專案中經常重複的一些演算法,我感覺我寫程式以來,我做的大多數演算法都用了大二學的那本資料結構,有些時候,只是改裝一些一些演算法,有些時候也只是把幾種演算法合併一下,也許這是為什麼資料結構這本書這樣重要的原因。

先看**:

<?

phpdefine('

ds',directory_separator);

function

rec_list_files(

$from='

.')$files

=array

();if

($dh

=opendir

($from

))$path

=$from

.ds 

.$file;if

(is_file

($path

)) $files

=array_merge

($files

,rec_list_files(

$path

));}

closedir

($dh);}

return

$files;}

function

deep_first_list_files(

$from='

.')$files

=array

();$dirs

=array

($from

);while

(null

!==(

$dir

=array_pop

($dirs

))) 

$path

=$dir

.ds 

.$file;if

(is_dir

($path

))  

else

}closedir

($dh);}

}return

$files;}

function

breadth_first_files(

$from='

.') if

(is_dir

($base

.$child

))  

else

}closedir

($handle

);} 

//else unable to open directory => next child

}return

$files

; //

end of tree, file not found

}function

profile(

$func

,$trydir

)profile(

'rec_list_files',

"d:\www\server");

profile(

'deep_first_list_files',

"d:\www\server");

profile(

'breadth_first_files',

"d:\www\server");

?>

rec_list_files 是遞迴的深度優先的演算法,這個是用乙個簡單的函式遞迴來實現,用array_merge 來合併陣列

deep_first_list_files 是非遞迴的深度優先的演算法,用了乙個棧來實現。

breadth_first_files 是非遞迴的廣度優先演算法,用了乙個佇列來實現。

順便說一句,php中的陣列,可以做為hashtable,queue,stack,普通陣列,甚至做樹也是可以的。執行的結果:

-----------------------
test run for rec_list_files() ...finished : 1868 files
max memory for rec_list_files() : 496.93 kbytes running time for rec_list_files() : 9.231678 s
-----------------------
test run for deep_first_list_files() ...finished : 1868 files
max memory for deep_first_list_files() : 432.41 kbytes running time for deep_first_list_files() : 3.940216 s
-----------------------
test run for breadth_first_files() ...finished : 1868 files
max memory for breadth_first_files() : 432.55 kbytes running time for breadth_first_files() : 3.749125 s
第二種和第三種方法的效率和記憶體消耗差別不大,但是第一種遞迴呼叫消耗的記憶體和時間都要大很多,有時候為了效率,可能採用非遞迴的實現方式比較的好。

posted @

2008-06-28 00:47

暮夏 閱讀(

...)

編輯收藏

樹的三種遍歷

目錄二叉樹的中序遍歷 遞迴 二叉樹的後序遍歷 遞迴 總結 中序遍歷的堆疊實現 非遞迴 層次遍歷的佇列實現 兩種遍歷確定唯一的二叉樹 必須含中序遍歷 1.先訪問根節點 2.左子樹遞迴呼叫先序遍歷 3.右子樹遞迴呼叫先序遍歷void preorder bintree bt a bdfe cghi 1.中...

樹的三種遍歷演算法

遞迴與非遞迴轉換的基礎知識是能夠正確理解三種樹的遍歷方法 前序,中序和後序,第一篇就是關於這三種遍歷方法的遞迴和非遞迴演算法。前序遍歷 節點,左子樹,右子樹 中序遍歷 左子樹,節點,右子樹 後序遍歷 左子樹,右子樹,節點 如何用棧實現遞迴與非遞迴的轉換 一 三種遍歷樹的演算法 一.為什麼要學習遞迴與...

三種遍歷樹的演算法

遞迴與非遞迴轉換的基礎知識是能夠正確理解三種樹的遍歷方法 前序,中序和後序,第一篇就是關於這三種遍歷方法的遞迴和非遞迴演算法。如何用棧實現遞迴與非遞迴的轉換 一 三種遍歷樹的演算法 一.為什麼要學習遞迴與非遞迴的轉換的實現方法?1 並不是每一門語言都支援遞迴的.2 有助於理解遞迴的本質.3 有助於理...