樹的遍歷與圖的遍歷


  研發時候,不要受原來的術語的影響,其實就是想着原來學過的或者看過的可以解決新遇到的問題,這其實是僥幸心理,忘記原來的術語吧,那只是你創新的源泉。

  遍歷就是把節點按一定規則構成一個線性序列,不同的規則得到不同順序的線性序列,僅此而已 。

  算法是實際問題工作步驟的抽象,不要一味想算法,想想實際情況怎么做的,然后提取算法,然后優化。

  不論怎樣,要和具體的數據結構結合在一起。

一、樹的遍歷

  對於樹的遍歷,有三種,就拿前序遍歷來說,得到的序列不論怎么拆分(子串,就是要連續),始
終要是根左右,跟在左右前面,左在右前面,有點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用棧。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM