樹的概念在開發裡面是很重要的一部分,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 有助於理...