深さ優先トラバーサルおよび階層ツリーの幅優先トラバーサル(Java実装)

深さ優先トラバーサルおよび階層ツリーの幅優先トラバーサル(Java実装)

深さ優先トラバーサルと幅優先トラバーサルは、実際に深い/ワイドトラバースのように多くの一連の直接構造をマッピングするトラバーサル方法を適用し、マルチレベル木は、特別なマップとして見ることができ、グラフアルゴリズムの一種です。

店舗ページへのエンジニアリングのバックエンドは、あなたのビジネスはほとんど変化缶を必要に応じている限り、使用された場合、この記事はトラバーサルの深さと幅トラバーサルの例を提供し、通常のリンケージカテゴリレベルの多段ツリー形式です。

私たちは、再帰的、非再帰的な方法を2つ通過することを知っています。再帰が、システムのバーストを作るスタックすることは非常に容易であるため、プロジェクトでは、一般的なアプローチは、再帰を無効にすることです。それは非再帰的な方法を採用するのが最善であると同時に、JVMはまた、再帰の最大数を制限し、それはあなたのツリー構造に異常にStackOverflowErrorの傾向があることは非常に深いです。

ノードモデル

public class Node {
    //值
    public int value;
    //所有的子节点
    public ArrayList<Node> nexts;

    public Node(int value) {
        this.value = value;
    }
}

深さ優先探索

深さ優先探索DFSすなわち深さ優先探索の英語の略語深い支店にそれぞれの可能なパスは、これまで先に進むことができず、各ノードは一度だけアクセスすることができるため。手順は簡単です。図特定のマルチレベル木構造として見ることができ、この方法は、一般的に同じ横断あり、スタックとセットで動作するようにしています。

主な手順:

  1. スタック構造のセットとセットの構造を用意し、記録用と子供用のスタックは、ノードにトラバースされていない、トラバーサルの歴史を記録するように設定
  2. 最初のノードがスタックに追加され、設定されています
  3. ポップ最初のノードを取得します。
  4. 最初のノードからの深さを横断開始し、注釈を以下のサンプルコードは、ほとんど理解されます。
public static void dfs(Node node) {
    if (node == null) {
        return;
    }
    Stack<Node> stack = new Stack<>();
    HashSet<Node> set = new HashSet<>();
    stack.add(node);
    set.add(node);
    System.out.println(node.value);
    
    while (!stack.isEmpty()) {
        //弹栈获得一个节点
        Node cur = stack.pop();
        //查看这个节点的所有孩子
        for (Node next : cur.nexts) {
            //如果有孩子是之前没有遍历到的,说明这个节点没有深度遍历完
            if (!set.contains(next)) {
                //此节点与其孩子加入栈与Set中
                stack.push(cur);
                stack.push(next);
                set.add(next);
                System.out.println(next.value);
                break;
            }
        }
    }
}

幅優先トラバーサル

(また、幅優先探索としても知られる)幅優先探索アルゴリズムは、最も簡単な検索アルゴリズムグラフの一方、このアルゴリズムプロトタイプアルゴリズムも多くの重要な図です。マルチシリーズのために、それは、子ノード内のすべての子を横断次いで、ノードのすべての子を横断する最初され、その後、下層の層を横断する横断します。

主なアイデアは、その後、順次、それを横断する、レコードの次の層内のすべてのノードにキューを使用することです。

public static void bfs(Node node) {
    if (node == null) {
        return;
    }
    Queue<Node> queue = new LinkedList<>();
    //用来注册已加入队列的节点——>防止重复添加节点
    HashSet<Node> set = new HashSet<>();
    queue.add(node);
    set.add(node);
    while (!queue.isEmpty()) {
        Node cur = queue.poll();
        System.out.println(cur.value);
        //将节点的所有下游节点加入到队列
        for (Node next : cur.nexts) {
            if (!set.contains(next)) {
                set.add(next);
                queue.add(next);
            }
        }
    }
}

おすすめ

転載: www.cnblogs.com/keeya/p/11487465.html