データ構造とアルゴリズムの基礎 (Wang Zhuo) (26): 深さ優先トラバーサル アルゴリズム DFS と幅優先トラバーサル アルゴリズム BFS

目次

深さ優先トラバーサル アルゴリズム DFS:

隣接行列:

隣接リスト:

最初に私は次のように書きました (最初のバージョン)。

質問:

最終製品:

幅優先トラバーサル アルゴリズム BFS

隣接リスト:

私は書きます:

隣接行列:


深さ優先トラバーサル アルゴリズム DFS:

隣接行列:

#include<iostream>
using namespace std;

typedef int Status;
#define MaxInt 999999  //表示无穷大
#define MVNum 100  //最大顶点数
//MAX Vertex Number
typedef char VertexType;  //设顶点类型:字符型
typedef int ArcType;  //设边的权值类型:int型

struct AMG
{
    VertexType vex[MVNum];  //顶点表
    ArcType arc[MVNum][MVNum];  //邻接矩阵
    int VexNum, ArcNum;  //(图)当前:顶点数和边数
};  //Adjacency Matrix Graph

//深度优先遍历算法(邻接矩阵)
int visited[MVNum] = {};    //未访问时元素全部为空

void DFS(AMG G, int v)
{
    int w;
    //访问第v个结点
    cout << G.vex[v]; //输出顶点内容
    //cout << v << endl;
    visited[v] = 1;
    //依次检查邻接矩阵v所在的行
    for (w = 0; w < G.VexNum; w++)
        //从邻接矩阵的第v行的第1个元素开始-遍历到该行第n个元素
    {
        if ((G.arc[v][w] != 0) && !visited[w])
            //相连且未被访问过
            DFS(G, w);
    }
        //算法时间复杂度O(n^2)
}

int main()
{

}

隣接リスト:

最初に私は次のように書きました (最初のバージョン)。

void DFS(ALG G, int v)
{
    int w,i=0;
    ArcNode* p=G.vex->firstarc;
    //访问第v个结点
    while (i < v)
    {
        p = p->nextarc;
        i++;
    }
    cout << p->adjvex; //输出顶点内容位置
    visited[v] = 1;
    //依次检查邻接矩阵v所在的行
    for (w = 0; w < G.vexnum; w++)
        //从邻接矩阵的第v行的第1个元素开始-遍历到该行第n个元素
    {
        p = p->nextarc;
        if ((p->adjvex) && !visited[w])
//        if ((G.vex[v][w] != 0) && !visited[w])
            //相连且未被访问过
            DFS(G, w);
    }  
}

ここで、私たちは多くの論理的誤りを犯します(陥ります)。

質問:

(1):

私たちが書いた関数: 最初は、i 番目の頂点ではなく、最初の頂点の i 番目の要素です。

さらに、最初のステップで出力したいのはエッジ ノードではなく頂点です。

(2):

最終的な判定文はポインタ変数を新規に作成した方が良いと思います。そうしないと後でpが混乱しやすい気がします。

 ははは、ナンセンス、実際、将来的にはこれは必要ありません 


最終製品:

//深度优先遍历算法
int visited[MVNum] = {};    //未访问时元素全部为空
void DFS(ALG G, int v)
{
    int w,i=0;
    cout << G.vex[v].data; 
    visited[v] = 1;
    ArcNode* p = G.vex[v].firstarc;
    while (p != NULL)
    {
        if (visited[p->adjvex] != 0)
            DFS(G,p->adjvex);
        p = p->nextarc;
    }
}

ちなみに、リンクされたリストを確認してください [i 番目の要素を取得します]。

Status 取第i个元素(LinkList L, int i, Elemtype e)
{// GetElem“i”
    LinkList p;
    p = L->next;
    int j = 1;
    while (p && i > j)
    {         p = p->next;         j++;     if (i < 0 || i <     j || !p) は         false を返します。     e = p->データ;     true を返します。}








幅優先トラバーサル アルゴリズム BFS

幅: 幅; (知識、興味など) 広範囲にわたる

隣接リスト:


私は書きます:

int visited[MVNum] = {};    
void BFS(ALG G, int v)
{
    cout << G.vex[v].data;
    visited[v] = 1;
    SqQueue Q;
    InitQueue(Q);
    EnQueue(Q, G.vex[v].firstarc->adjvex);//从第一个顶点开始遍历
    auto i = G.vex[v].firstarc;//指向(代表)链头
    while (!QueneEmpty(Q))//直至队空结束
    {
        auto j = i;//用于指向访问各个元素节点
        while (j != NULL)//当结点为空(链尾,结束了)结束循环
        {
            if (visited[j->adjvex] == 0)//入队【没被访问过的】元素
            {
                EnQueue(Q, j->adjvex);
            }
            j = j->nextarc;//指向下一轮循环
            visited[j->adjvex] = 1;//别忘了
        }
        DeQueue(Q, i->adjvex);//出队队头
        cout << j->adjvex;
        //输出出队的元素,当然这里出队和输出在循环开始时操作也可以
    }
}

詳細な学習プロセスとプロセス全体で踏まれたすべての落とし穴については、以下を参照してください。

データ構造とアルゴリズムの基礎 (Wang Zhuo) (24) 添付資料: 隣接リストの幅優先トラバーサル アルゴリズム BFS (学習プロセス レコード)_宇-Yu のブログ - CSDN ブログ


隣接行列:

void BFS(AMG& G)
{
    for (int v = 0; v < G.VexNum; ++v)
    {
        for (int w = 0; w < G.VexNum; ++w)
        {
            if ((G.arc[v][w] != 0) && visited[w] == 0)
            {
                cout << G.vex[w];
                visited[w] = 1;
            }
        }
    }
    //算法时间复杂度O(n^2)
}

これは出力に1つずつアクセスするように書かれているような気がします

でも、それは問題ではありません、これはそれほど重要ではありません、そしてそれは結局書くことができます

おすすめ

転載: blog.csdn.net/Zz_zzzzzzz__/article/details/130054425