Javascriptの木の構造


最前線
    先端にデータ構造を設計することは多くないです.一番よく使うのは木の構造に対する操作です.ある意味、先端作業自体は木の構造に関わる仕事の方向です.結局、DOMは天然の木の構造です.だからどのように良好に木の構造を操作することができますか?先端技術者には欠かせない能力です.
ツリー構造
定義
    木の構造は何ですか?データ構造の観点から:
  • ツリーは、非線形データ構造
  • である.
  • 各ノードは、0以上の子孫があるかもしれない
  • .
  • 各ノードは、唯一の親ノードを備えている(複数の親ノードがあるなら、それは図である)
  • .
    カテゴリ
    ツリーはノードによって異なるタイプに分けられます.最も一般的な分類は以下の通りです.
  • 二叉木
  • フォーク検索ツリー
  • バランス二叉ルックアップツリー
  • マホガニー
  • 具体的に彼らの違いはここで詳しく説明しません.詳しく調べてください.
    先端によくある木の構造
    DOMツリー構造
    以下のhtml構造は天然の木の構造です.各Domノードの下には、0/1/複数のサブノードがある.
    オブジェクトツリー構造
  • 配列形式
  • 特徴:各対象ノードは、以下にチルドレンがあるかもしれないし、チルドレンがないかもしれない.
    let obj = [
        {
            id: 1,
            type: 'dom',
            children: [
                {
                    id: 2,
                    type: 'html'
                }
            ]
        },
        {
            id: 3,
            type: 'css',
            children: [
                {
                    id: 4,
                    type: 'javascript'
                }
            ]
        }
    ];
  • オブジェクト形式
  • 最も一般的なのは抽象的な文法ツリーです.
    特徴:対象の属性の下には異なる属性があり、それぞれの属性の下には異なる属性があります.
    このフォーマットはよくデータ統計に出ます.
    Javascriptの木の構造の遍歴
        実は私の考えでは、木の構造はいろいろありますが、先端作業では、ツリーノードの修正などの操作がほとんど触れられません.
    需要シーン:以下はDomツリー構造の例である:
    1、各ノードの名前とノードの深さを出力する必要があります.
    3、深さ優先と広さ優先を実現する必要があります.
  • 対応するツリー構造があると仮定して、サブノードはchildNodes(なぜchildrenを使わないのですか?自分で調べてみます.)
  • です.
    深さ優先巡回
    深さ優先巡回は、DFS(deep first search)とも呼ばれ、トラバース順序は、優先的にノードのサブノードをトラバースし、次にノードの兄弟ノードである.
  • 再帰出力
  • function DeepSearch(node, deep = 0) {
        const child = node.childNodes;
    
        const { nodeName } = node;
        console.log(`name:${nodeName},deep:${deep}`);
    
        for(let i = 0, len = child.length; i < len; i++) {
            DeepSearch(child[i], deep + 1);        
        }
    }
  • 非再帰出力
  • function deepSearch(node, deep = 0) {
        const stack = [];
        const deepArr = [];
        stack.push(node);
        deepArr.push(0);
        while(stack.length !== 0){
            const node = stack.shift();
            const deep = deepArr.shift();
    
            const { nodeName } = node;
            console.log(`name:${nodeName},deep:${deep}`);
    
            const nodes = child.childNodes;
            for( let i = node.length; i > 0; i--) {
                stack.unshift(nodes[i]);
                deep.unshift(deep + 1);
            }
        }
    }
    広さ優先巡回
    広さ優先は、ちょうど深さ優先策とは反対に、先にノードの兄弟ノードを巡回して、サブノードを巡回する.
  • 再帰出力
  • function BreadSearch(node, deep = 0) {
        const child = node.childNodes;
        const res = [];
    
        for(let i = 0, len = child.length; i < len; i++) {
    
            const { nodeName } = node;
            console.log(`name:${nodeName},deep:${deep}`);
    
            res.push(child[i]);
        }
    
        DeepSearch(res, deep + 1);        
    
    }
  • 非再帰出力
  • function breadSearch(node, deep = 0) {
        const stack = [];
        const deepArr = [];
        stack.push(node);
        deepArr.push(0);
        while (stack.length !== 0 ) {
            const node = stack.shift();
            cosnt deep = stack.shift();
            const { nodeName } = node;
            console.log(`name:${nodeName},deep:${deep}`);
    
            for(let i = 0, len = child.length; i < len; i++) {
                stack.push(child[i]);
            }
        }
    }
    ビジネスシーン
    先端の木の動作は、常に特定のツリー構造を生成する.よくあるシーンでは、ルートを生成し、メニューを生成することがあります.
    ルート
    react-routerを例に説明する.
    簡単な状況(bad)
    一般的に、react-routerのルートは以下の通りです.
    
        
        
        
        ... ...
    
    しかし、すべては上記の書き方に従って、ルートを加えるごとに、内容の下に取り、もう一つ追加してください.
        
    コードの維持が容易ではないし、読み取り可能性も良くない.
    配置の方式(better)
    配置の方式はいつもよりよく、ルーティングの内部コードを開くたびに修正される.
    const routers = [
        {
            path: '/a',
            component: A
        },
        {
            title: '  ',
            id: 'exam',
            path: '/b',
            children: [
                {
                    path: '/c',
                    component: C
                },
                {
                    path: '/d',
                    component: D
                }
            ]
        }
    ];
    
    function getRoute (routes, rootPath = '') {
        let res = [];
        for (let i = 0, len = routes.length; i < len; i++) {
            const route = routes[i];
            const { path } = route;
            if (route.children) {
                res = [...res, ...getRoute(route.children, path)];
            } else {
                res.push(
                    
                );
            }
        }
        return res;
    };
    
    
        {
            getRoute(routers)
        }
    
    メニュー
    メニューとルートの方式はとても似ています.そして、いつも一緒に使っています.具体的な書き方はここで詳しく説明しません.あまりにも似ているので、残しておきましょう.
    参考資料