[データ構造] [バイナリツリー] 5。グラフの深さ優先トラバーサル(DFS)&&幅優先トラバーサル(BFS)

1.深さ優先探索(DFS)

1.理解する

1.1二分木のプレオーダートラバーサルを確認します

深さ優先走査は二分木での事前順序走査のようなものです。1つの極が最後に挿入され、前に移動してから前のノードに戻って、別の分岐があるかどうかを確認することが不可能であることがわかります。ある場合は、1つの極が最後に挿入されます。ない場合は、最後のノードに戻り、左右のノードがトラバースされるまで繰り返します。

のは、見てみましょうの先行順走査バイナリツリーを最初
ここに画像の説明を挿入
前順走査手順を

:ルートノードAから始めて、左サブツリー、左サブツリー、左サブツリーを無意識に歩きます... Gに到達するまで、彼には左子ノードがありません。つまり、左サブツリーがありません。この図のバイナリツリーが比較的簡単で、かつので、右の子の木は、Gが行くする権利サブツリーを持っていない、それはに戻ります前のノードのD G ;

:Dの左のサブツリーはすでに歩いているので、Dの右のサブツリーに移動します。

:Dの右のサブツリーを真新しいツリーと見なします。つまりDの右のサブツリーのルートノードH入った後、考えずに左のサブツリーを歩くことができます。この図の二分木は比較的単純なので、Hは左のサブツリーがないので、Hの右のサブツリーを見てください。ない場合は、Dにフォールバックします。

Dの左右のサブツリーがなくなり、次のDにはトラバースされない子ノードがないため、1つのノードBD戻されBの右側のサブツリーが見つかり、ないことがわかりました。その後、Aに返されます。

Aは、サブツリーが経験してきた左、左に行くために、新しいツリーとして、Aの右部分木を右サブツリーを、最初の非脳は左のサブツリーを行って、その後、に戻った......

1.2グラフの深さ優先走査(DFS)

グラフについても同じことが言えます。ルートノードを取得したら、最初に前のノードがなくなるまでポールを挿入してから、前のノードに戻って別の分岐道路があるかどうかを確認します。ある場合他の分岐道路を処理します。真新しいグラフとしての分岐道路。行き来します。そうでない場合前のノード戻って、道路に別の分岐があるかどうかを確認します。

違いは次のとおりです。

:グラフがリングの場合があります。つまり、頭や尾がありません。したがって最後ポールを挿入する過程で通過したノードに遭遇した場合は、のジャンクション到達したことを意味します。頭と尾のリング、その後、前方に行く彼らがそう後退を開始、もはや前進していない、すべてトラバースされているノードです。

二分木のノードの場合、次のステップに進むとき左のサブツリーと右のサブツリーの2つの選択肢しかなくグラフに3つ、4つ、5つ、またはそれ以上のフォークがあります。したがって、各フォークが確実に渡されるように、whileループまたはforループを使用する必要があります。

グラフの深さ優先走査(DFS)は、次の図に示すとおりです。
ここに画像の説明を挿入
最初に0-> 1-> 2-> 3-> 4-> 5の順序に従って、次の5が0、そしてそれは通過しました。それで、5戻ってウォークスルーされていない別のノードが5にあるかどうかを確認ます。Gが見つかったので、Gは考えずにダウンします。

G-> Hの、Hの次のノードもすべて渡されたことがわかったので、Gに戻って渡さていない次のノードあるかどうかを確認ます。次のノードがない場合、戻ります。までG - > F - > E - > D、それはDが持つことが判明したのノードI歩いていないので、私はに行くIを

歩いた、歩いていない次のノードがないことがわかったのでルートノードに戻るまでフォールバックを続けました。D- > C-> B-> Aトラバーサル全体は以上。

2.コード

以下では、隣接リストに基づいた深さ優先走査(DFS)アルゴリズムを投稿ます。その前に、隣接リストを簡単に紹介します

以下に示すように、隣接テーブルはリンクリストノードの配列を使用してすべてのノードを格納し、リンクリストを使用して現在のノードに隣接するすべてのノードを格納します。
ここに画像の説明を挿入
その中で、最初の行のABCDEFGHIは配列であり、配列タイプははListNode(リンクリストノード)です。次に、配列内の各要素は、上の図の隣接リストを構成する独自の隣接ポイントを指します。

上記の隣接テーブルの保存方法に基づいて、深さトラバーサルの手順は次のようになります。

このプログラムは、別のブログ投稿のプログラムを基にしています。
元のプログラムは次のとおりです。CSDNブロガーのブログ投稿データ構造[MistyRain Blurred Half World War] :グラフトラバーサル(1:深さ優先トラバーサル)

int visited[G_numVertexes];//用一个visited数组来记录某个节点是否被遍历过:1表示遍历过;0表示没有遍历过。其中 ,G_numVertexes是图中节点的个数,也是邻接表中第一行那个数组的元素个数

void DFSTraverse(ListNode *G) {
    
    
    for (int i = 0; i < G_numVertexes; i++)
    {
    
    
        visited[i] = 0; //把visited数组的所有元素都初始化未0,表示都没遍历过
    }
    for (int i = 0; i < G_numVertexes; i++) //为了防止不连通图的特殊情况,在这里对每个节点都进行遍历
    {
    
    
        if (visited[i] == 0)
        {
    
    
            DFS(G, i); //对未遍历过的节点,调用DFS函数
        }
    }
}


void DFS(ListNode *G, int i) {
    
    
    EdgeNode *p;
    visited[i] = 1; //把这个节点的访问标志位设为1,表示已遍历过
    cout << G[i]->data << endl; //打印当前节点
    
    p = G[i]->adjvex; //根据邻接表的存储方式,把p设为G[i]的第一个邻接点
    while (p)
    {
    
    
    	cout << p->data << endl;
        if (!visted[p->adjvex]) //如果G[i]的另一个邻接点未遍历过,则遍历它
        {
    
    
            DFS(G, p->adjvex); //递归访问
        }
        p = p->next;
    }
}

第二に、幅優先探索(BFS)

1.理解する

2.コード

おすすめ

転載: blog.csdn.net/qq_39642978/article/details/112061940