廣度優先搜索,深度優先搜索-JavaScript前端
摘要:node
掌握好數據結構對前端和後端都頗有必要,js中DOM能夠跟樹這種數據結構聯繫起來,相信你們都不陌生。算法
遍歷下面這顆DOM樹,遍歷到節點時,打印當前節點和類名後端
<div class="root"> <div class="box1"> <p class="pnode">nini</p> </div> <div class="box2"> </div> <div class="box3"> <span class="spannode">lalal</span> </div> </div>
1. 深度優先搜索數組
深度優先遍歷是指從某個頂點出發,首先訪問這個頂點,而後找出剛訪問這個結點的第一個未被訪問的鄰結點,而後再以此鄰結點爲頂點,繼續找它的下一個頂點進行訪問。重複此步驟,直至全部結點都被訪問完爲止。數據結構
下面是深度優先搜索的順序圖ide
遞歸版:spa
非遞歸版:3d
function deepTraversal(node) { let nodes = []; if(node != null) { let stack = []; //存放未來要訪問的節點 stack.push(node); while(stack.length !=0) { let item = stack.pop(); //正在訪問的節點 nodes.push(item); let childrens = item.children; for(let i = childrens.length-1; i>=0; i--) { //將如今訪問的節點的子節點存入stack,供未來訪問 stack.push(childrens[i]) } } } return nodes; }
非遞歸版呢,先把元素放在數組裏,而後是把數據的最後一項pop出去,判斷當前元素是否有子節點,若是有的話推動數組裏,直到數組裏沒有數據中止循環。 code
2. 廣度優先搜索
廣度優先遍歷是從某個頂點出發,首先訪問這個頂點,而後找出剛訪問這個結點全部未被訪問的鄰結點,訪問完後再訪問這些結點中第一個鄰結點的全部結點,重複此方法,直到全部結點都被訪問完爲止。
下面是廣度優先搜素的順序圖:
遞歸版:
function wideTraversal(node) { let nodes = [],i=0; if(node != null) { nodes.push(node); wideTraversal(node.nextElementSibling); node = nodes[i++]; wideTraversal(node.firstElementChild); } return nodes }
非遞歸版:
function wideTraversal(node) { let nodes = [],i=0; if(node != null) { let stack = []; //存放未來要訪問的節點 stack.push(node); while(stack.length !=0) { let item = stack.shift(); //正在訪問的節點 nodes.push(item); let childrens = item.children; for(let i = 0; i<childrens.length; i++) { //將如今訪問的節點的子節點存入stack,供未來訪問 stack.push(childrens[i]) } } } return nodes }
廣度優先搜索非遞歸版和深度優先搜索的遞歸版思想差很少,一個是pop最後一個元素,一個是shift第一個元素,再把子元素放在一個數組最後,這樣再進行數組的處理時會先遍歷父元素,子元素最後遍歷。達到廣度搜索的目的。
結論:
對於深度優先搜索來講,打印了兩個的執行速度,遞歸的處理速度相對較快點,可是對於廣度優先搜索來講,非遞歸的執行速度比較快點。因此每一個搜索都有本身的最好的算法。