图的遍历之深度优先搜索(Depth-First Search—DFS)

描述

从根节点开始的递归深度优先搜索与树的前序遍历(preorder traversal)类似,是前序遍历的推广。从某个顶点V开始处理,然后递归地遍历所有与顶点V邻接的且没有被访问过的顶点。算法的基本思想如下:
假设图G初态为所有顶点未被访问(visited[i]=false),从G中任选一顶点vi :

  1. 从该顶点vi出发,首先访问vi,,置visited [vi ]=true;
  2. 然后依次搜索vi的每一个邻接点vj ;
  3. 若vj未被访问过,则以vj为新的初始出发点,重复1;若vj已被访问过,则返回到vi另一个邻接点,重复3
  4. 如果经过1、2、3后,图中仍有未被访问的顶点,再从中任选一顶点,重复1、2、3,直至所有顶点都被访问过,遍历结束。

如上图所示,左边的是深度优先搜索,右边是广度优先搜索。深度优先搜索是从顶点到顶点,对于给定的顶点尝试过每一种可能后,就退到上一个顶点来尝试下一个顶点。宽度优先搜索则是尝试一个顶点的所有可能之后,才访问下一个顶点。

深度优先搜索的算法模板:

void Dfs(Vertex V)
{
    Visited[v] = True;
    for each W adjacent to V
        if(!Visited[W])
            Dfs(W);
}

测试代码

(图的存储是邻接表的深度优先搜索)

#include <iostream>
using namespace std;

#include <stdio.h>
#include <stdlib.h>

#define Max_Vertex_Num 100 //最大顶点数

typedef char VertexType;      //顶点数类型定义
typedef int EdgeType;        //边类型定义

typedef struct EdgeNode
{
    int adjvex;               // 该边所指的顶点的位置
    EdgeType weight;          //该边的权值
    struct EdgeNode *NextEdge; //指向下一条边的指针
}EdgeNode;

typedef struct VertexNode
{
    VertexType data;     // 顶点信息
    EdgeNode *firstEdge;  //指向第一条依附该顶点的边表头指针
}VertexNode, AdjList[Max_Vertex_Num];

typedef struct
{
    AdjList adjList;
    int EdgeNum;    // 图的当前边数
    int VertexNum;  //图的当前顶点数
    bool visited[Max_Vertex_Num];  //顶点是否被访问过
}ALGraph;

// 返回顶点v的位置
int LocateVertex(ALGraph *G, VertexType v)
{
    int i = 0;
    for(i = 0; v != G->adjList[i].data && i < G->VertexNum; i ++);

    if(i >= G->VertexNum)
        return -1;
    return i;
}

//增加节点
void AddVertex(ALGraph *G)
{
    cout << "input vertex number" << endl;
    cin >> G->VertexNum;

    cout << "input vertex value" << endl;
    for(int i = 0; i < G->VertexNum; i++)
    {
        cin >> G->adjList[i].data;
        G->adjList[i].firstEdge = NULL;
    }
}

//增加边表
void AddEdge(ALGraph *G)
{
    cout << "input edge number" << endl;
    cin >> G->EdgeNum ;
    VertexType V1, V2;
    cout << "input two vertex" << endl;
    for(int k = 0; k < G->EdgeNum; k ++)
    {
        cin >> V1 >> V2;
        int i = LocateVertex(G,V1);
        int j = LocateVertex(G,V2);

        EdgeNode *pe1 = (EdgeNode *)malloc(sizeof(EdgeNode));
        pe1->adjvex = i;
        pe1->NextEdge = G->adjList[j].firstEdge;
        G->adjList[j].firstEdge = pe1;

        EdgeNode *pe2 = (EdgeNode *)malloc(sizeof(EdgeNode));
        pe2->adjvex = j;
        pe2->NextEdge = G->adjList[i].firstEdge;
        G->adjList[i].firstEdge = pe2;

    }
}

void CreatALGraph(ALGraph *G)
{
    AddVertex(G);
    AddEdge(G);
}

void PrintALGrap(ALGraph *G)
{
    EdgeNode *pe;
    cout << "编号 顶点 邻点编号" << endl;

    for(int i = 0; i < G->VertexNum; i ++)
    {
        cout << " " << i << " " << G->adjList[i].data << " ";
        for(pe = G->adjList[i].firstEdge; pe; pe = pe->NextEdge)
            cout << pe->adjvex << " ";
        cout << endl;
    }
}

// 深度搜索
void DFS(ALGraph *G, int i)
{
    EdgeNode *pe;

    G->visited[i] = true;

    cout << G->adjList[i].data << " ";  //打印顶点
    pe = G->adjList[i].firstEdge;

    while(pe)
    {
        if(!G->visited[pe->adjvex])
            DFS(G,pe->adjvex);
        pe = pe->NextEdge;
    }

}

void DFS_Traverse(ALGraph *G)
{
    int i = 0;
    for(i = 0; i < G->VertexNum; i ++)
        G->visited[i] = 0;
    for(i = 0; i < G->VertexNum; i ++)
        if(!G->visited[i])
            DFS(G,i);
}

int main()
{
    ALGraph GL;
    CreatALGraph(&GL);
    PrintALGrap(&GL);
    DFS_Traverse(&GL);
}

(图的存储方式邻接矩阵的深度优先搜索)

#include <iostream>
using namespace std;


const int VERTEX_NUM = 20;    // 顶点的最大数

typedef int graph_weight_t;   // 边的权值类型 可以为 int float double
typedef struct SArc
{
    graph_weight_t Weight;            // 权值
}AdjMatrix[VERTEX_NUM][VERTEX_NUM];   // 邻接矩阵

typedef struct SGraph
{
    int       iVertexNum;     // 顶点数
    int       iArcNum;        // 边数
    int       aVertex[VERTEX_NUM];  // 顶点向量
    AdjMatrix mArcs;          //邻接矩阵
    bool visited[VERTEX_NUM];
}Graph;

void IintGraph(Graph &graph)
{
    //graph = (pGraph)malloc(sizeof(Graph));
    graph.iVertexNum = 0;
    graph.iArcNum    = 0;
    for(int i = 0; i < VERTEX_NUM; i++)
        graph.aVertex[i] = 0;
    for(int i = 0; i < VERTEX_NUM; i ++)
        for(int j= 0; j < VERTEX_NUM; j ++)
            graph.mArcs[i][j].Weight = 0;
}

void Add_Vertex(Graph &graph)
{
    cout << "Add Vertex" << endl;
    cout << "Input vertex number:";
    cin >> graph.iVertexNum;

    cout << "Input vertex value:";
    for(int i = 0; i < graph.iVertexNum; i ++)
        cin >> graph.aVertex[i];
}

int Locat_vertex(Graph &graph, int vertex)
{
    for(int i = 0; i < graph.iVertexNum; i ++)
    {
        if(graph.aVertex[i] == vertex)
            return i;
    }

    return -1;
}

void Add_Arcs(Graph &graph)
{
    cout << "Add Arcs" << endl;
    cout << "input arcs numbers:";
    cin >> graph.iArcNum;

    int   iFirst           = 0;
    int   iSecond          = 0;
    int   iRow             = 0;
    int   iCol             = 0;
    graph_weight_t iWeight  = 0;
    for(int i = 0; i < graph.iArcNum; i ++)
    {
        cout << "Input two Arc and Weight(ex. 1 2 32)" << endl;
        cin >> iFirst >> iSecond >> iWeight;

        iRow   =  Locat_vertex(graph, iFirst);
        iCol   =  Locat_vertex(graph, iSecond);

        graph.mArcs[iRow][iCol].Weight = iWeight;
        graph.mArcs[iCol][iRow].Weight = iWeight;
    }

}

void Creat_Graph(Graph &graph)
{
    cout << "Creat Graph" << endl;
    Add_Vertex(graph);
    Add_Arcs(graph);
}

void Show_Graph(Graph &graph)
{
    cout << "show the graph represented by adjmatrix "<<endl;

    for(int row = 0; row < graph.iVertexNum; row ++)
    {
        for(int col =0; col < graph.iVertexNum; col ++)
        {
            cout << graph.mArcs[row][col].Weight << "\t";
        }
        cout << endl;
    }

}

void DFS(Graph &graph, int i)
{
    graph.visited[i] = true;

    cout << graph.aVertex[i] << endl;

    for(int j = 0; j < graph.iVertexNum; j ++)
    {
        if(graph.mArcs[i][j].Weight==1&&!graph.visited[j])
            DFS(graph,j);
    }
}

void DFS_traversal(Graph &graph)
{
    for(int i = 0; i < graph.iVertexNum; i ++)
        graph.visited[i] = 0;

    for(int j = 0; j < graph.iVertexNum; j ++)
    {
        if(!graph.visited[j])
            DFS(graph,j);
    }
}

int main()
{
    Graph graph;
    IintGraph(graph);
    Creat_Graph(graph);
    Show_Graph(graph);
    DFS_traversal(graph);
}



你可能感兴趣的:(图,DFS,深度优先搜索)