数据结构篇:图的遍历(一:深度优先遍历)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_15020543/article/details/84328609

深度优先遍历,也称作深度优先搜索,缩写为DFS

深度优先遍历从某个顶点出发,访问此顶点,然后从v的未被访问的邻接点触发深度优先便利图,直至所有和v有路径想通的顶点都被访问到。

这样我们一定就访问到所有结点了吗,没有,可能还有的分支我们没有访问到,所以需要回溯(一般情况下都设置一个数组,来记录顶点是否访问到,如果访问到就不执行DFS算法,如果未被访问过就执行DFS算法)

以这张图为例

我们约定,在没有碰到重复顶点的情况下,优先选择右手边

那么按深度优先遍历就是:A B C D E F G H(此时这条线路已经走到尽头,可是还有一个I顶点没有遍历,所以回到G,发现G的邻接点都遍历过了,再回到F,发现F的邻接点也都遍历过了。。。直到D顶点,发现I这个顶点没有遍历,所以把I再遍历,继续回溯,最终回到起点A) I

落实到代码就是


//访问标志的数组,为1表示访问过,为0表示未被访问
int visted[100];
//邻接表的深度优先遍历算法
void AdjacencyList::DFS(GraphAdjList *G, int i) {
    EdgeNode *p;
    visted[i] = 1;
    cout << G->adjList[i].data << "--";
    p = G->adjList[i].firstedge;
    while (p)
    {
        if (!visted[p->adjvex])
        {
            //递归访问
            DFS(G, p->adjvex);
        }
        p = p->next;
    }

}
//邻接表的深度遍历操作
void AdjacencyList::DFSTraverse(GraphAdjList *G) {
    //初始化所有顶点都没有访问过
    cout<<"深度优先遍历结果为:"<<endl;
    for (int i = 0; i < G->numVertexes; i++)
    {
        visted[i] = 0;
    }
    for (int i = 0; i < G->numVertexes; i++)
    {
        if (visted[i] == 0)
        {
            DFS(G, i);
        }
    }
}

完整代码

//
// Created by 烟雨迷离半世殇 on 2018/11/21.
//

#include <iostream>

using namespace std;

//访问标志的数组,为1表示访问过,为0表示未被访问
int visted[100];
//边表结点
typedef struct EdgeNode {
    //顶点对应的下标
    int adjvex;
    //指向下一个邻接点
    struct EdgeNode *next;
} edgeNode;

//顶点表结点
typedef struct VertexNode {
    //顶点数据
    char data;
    //边表头指针
    edgeNode *firstedge;
} VertexNode, AdjList[100];

//集合
typedef struct {
    AdjList adjList;
    //顶点数和边数
    int numVertexes, numEdges;
} GraphAdjList;

class AdjacencyList {
public:

    void CreateALGraph(GraphAdjList *G);

    void ShowALGraph(GraphAdjList *G);

    void DFS(GraphAdjList *G, int i);

    void DFSTraverse(GraphAdjList *G);

    void Test();


};

void AdjacencyList::CreateALGraph(GraphAdjList *G) {
    int i, j, k;
    edgeNode *e;
    cout << "输入顶点数和边数" << endl;
    //输入顶点数和边数
    cin >> G->numVertexes >> G->numEdges;
    //读入顶点信息,建立顶点表
    for (i = 0; i < G->numVertexes; i++)
    {
        //输入顶点信息
        cin >> G->adjList[i].data;
        //将边表置为空表
        G->adjList[i].firstedge = NULL;
    }
    //建立边表(头插法)
    for (k = 0; k < G->numEdges; k++)
    {
        cout << "输入边(vi,vj)上的顶点序号" << endl;
        cin >> i >> j;
        e = new EdgeNode;
        e->adjvex = j;
        e->next = G->adjList[i].firstedge;
        G->adjList[i].firstedge = e;

        e = new EdgeNode;

        e->adjvex = i;
        e->next = G->adjList[j].firstedge;
        G->adjList[j].firstedge = e;
    }
}

void AdjacencyList::Test() {
    cout << "ALL IS OK." << endl;
}

void AdjacencyList::ShowALGraph(GraphAdjList *G) {
    for (int i = 0; i < G->numVertexes; i++)
    {
        cout << "顶点" << i << ": " << G->adjList[i].data << "--firstedge--";
        edgeNode *p = new edgeNode;
        p = G->adjList[i].firstedge;
        while (p)
        {
            cout << p->adjvex << "--Next--";
            p = p->next;
        }
        cout << "--NULL" << endl;
    }

}

void AdjacencyList::DFS(GraphAdjList *G, int i) {
    EdgeNode *p;
    visted[i] = 1;
    cout << G->adjList[i].data << "--";
    p = G->adjList[i].firstedge;
    while (p)
    {
        if (!visted[p->adjvex])
        {
            //递归访问
            DFS(G, p->adjvex);
        }
        p = p->next;
    }

}

void AdjacencyList::DFSTraverse(GraphAdjList *G) {
    //初始化所有顶点都没有访问过
    cout<<"深度优先遍历结果为:"<<endl;
    for (int i = 0; i < G->numVertexes; i++)
    {
        visted[i] = 0;
    }
    for (int i = 0; i < G->numVertexes; i++)
    {
        if (visted[i] == 0)
        {
            DFS(G, i);
        }
    }
}


int main() {

    AdjacencyList adjacencyList;
    GraphAdjList *GA = new GraphAdjList;
    adjacencyList.Test();
    adjacencyList.CreateALGraph(GA);
    adjacencyList.ShowALGraph(GA);
    adjacencyList.DFSTraverse(GA);
    return 0;
}


以这张图为基准输入

运行结果

猜你喜欢

转载自blog.csdn.net/qq_15020543/article/details/84328609