研發時候,不要受原來的術語的影響,其實就是想着原來學過的或者看過的可以解決新遇到的問題,這其實是僥幸心理,忘記原來的術語吧,那只是你創新的源泉。
遍歷就是把節點按一定規則構成一個線性序列,不同的規則得到不同順序的線性序列,僅此而已 。
算法是實際問題工作步驟的抽象,不要一味想算法,想想實際情況怎么做的,然后提取算法,然后優化。
不論怎樣,要和具體的數據結構結合在一起。
一、樹的遍歷
對於樹的遍歷,有三種,就拿前序遍歷來說,得到的序列不論怎么拆分(子串,就是要連續),始
終要是根左右,跟在左右前面,左在右前面,有點DP類似最優子結構。
//中序 LDR
if(null)
{
return ;
}
else
{
//分別輸出左 根 右
}
無論前中后都是dfs,不過樹的話,由於有了明確的children字段,不需要設置vis數組來確保只遍歷一次,因為肯定知識便利了一次。
travel(node)
{
for(i=1:lengh)
{
//.....處理node節點
if(null!=children)
travel(children);
}
}
另一種寫法是把for循環寫在函數外面
樹的層次遍歷和BFS就很像了,總的來說就是DFS用棧,只不是棧是隱式棧,BFS用隊列,用的是顯式列。
1.初始化一個隊列,根入隊
2.取對頭,並訪問
3.若左節點非空,入隊;右節點非空入隊
4.隊不空,循環2 - 3,否則結束
二、圖的遍歷
2.1 BFS
自上而下,從左到右,也需要vis。是樹層次的推廣。
2.2 DFS
需要vis數組。是樹的先跟的推廣。
2.3 樹和圖區別與聯系
圖需要需要vis是怕循環遍歷,這和樹不一樣,數不可能循環遍歷。
相同點:從一點出發遍歷相鄰節點,對樹來說是左右孩子。
不同點:圖有多個相鄰點,二叉樹只有左右孩子,bfs需要vis記錄訪問過的節點。
比如a,左b右c,訪問a,然后bc如隊,然后訪問b,a和b相鄰,沒有vis的話a又要被訪問。
圖有不連通情況,樹的的dfs和bfs都不需要vis。
樹是一種特殊的圖。
三、線索樹
每個節點增加2個字段分別指向節點的前驅和后繼。前驅好搞,直接在travel增加一個參數parentID,初始為null,在for內,if外直接指向該parentID,后繼應該也不難,在if內,主要要看樹的數據結構。
四、非遞歸遍歷
BFS利用隊列保存尚未遍歷的節點或者子樹,DFS用棧。
