1. 程式人生 > >關於DOM節點的深度優先和廣度優先遍歷

關於DOM節點的深度優先和廣度優先遍歷

HTML的樹形結構如上

深度優先遍歷

對於樹的深度優先遍歷,執行結果應該如下:


採用遞迴方式
 var arr=[];
    //深度優先
    function traversalDFSDOM (rootDom) {
        if(!rootDom)return;
        if(rootDom.children.length==0){
            arr.push(rootDom)//沒有孩子節點,表示是個葉子節點,將節點push到陣列中
            return;
        }
        arr.push(rootDom)//非孩子節點,在每次遍歷它的孩子節點之前先把它push到陣列中
        for(var i=0;i<rootDom.children.length;i++){
            traversalDFSDOM(rootDom.children[i])//遞迴呼叫
        }

    }

結果如下

(script標籤寫在body外面,但是執行的時候瀏覽器會把它放到body中,變成最後一個元素)

採用非遞迴的方式
 //深度優先非遞迴
    function traversalDFSDOM(rootDom) {
        if(!rootDom)return;
        var stack=[]
        var node = rootDom;
        while(node!=null){
            arr.push(node);
            if(node.children.length>=0){
                for(let i=node.children.length-1;i>=0;i--)
                    stack.unshift(node.children[i]);
            }
            node = stack.shift()
        }
    }
    traversalDFSDOM(bodyDom)

非遞迴主要採取模擬佇列的方法過程:


以此類推,需要注意的是i的迴圈需要從node.children.length-1開始到0

廣度優先遍歷

對於DOM樹的廣度優先遍歷的結果應該如下
採用遞迴方式
var stack=[bodyDom];//bodyDom是遍歷的根節點
    function traversalBFSDOM (count) {
        count = count || 0;
        if (stack[count]) {
            var children = stack[count].children;
            for (let i = 0; i < children.length; i++) {
                stack.push(children[i]);
            }
            traversalBFSDOM(++count)
        }
    }
traversalBFSDOM(0)
採用非遞迴方式
    function traversalBFSDOM (rootDom) {
        if(!rootDom)return;
        arr.push(rootDom)
        var queue = [rootDom];
        while(queue.length){
            var node = queue.shift();
            if(!node.children.length){
                continue;
            }
            for(var i=0;i<node.children.length;i++){
                arr.push(node.children[i]);
                queue.push(node.children[i]);
            }
        }
    }

主要採用先進先出的思想,依次遍歷每個節點下的孩子節點。

執行結果如下:


學習是個過程,學會深入學習

祝自己生日快樂,感恩生活!