图的遍历之深度优先搜索(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);
}

时间: 2024-10-07 18:12:35

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

图的遍历之 深度优先搜索和广度优先搜索

本章会先对图的深度优先搜索和广度优先搜索进行介绍,然后再给出C/C++/Java的实现. 目录 1. 深度优先搜索的图文介绍 1.1 深度优先搜索介绍 1.2 深度优先搜索图解 2. 广度优先搜索的图文介绍 2.1 广度优先搜索介绍 2.2 广度优先搜索图解 3. 搜索算法的源码 深度优先搜索的图文介绍 1. 深度优先搜索介绍 图的深度优先搜索(Depth First Search),和树的先序遍历比较类似. 它的思想:假设初始状态是图中所有顶点均未被访问,则从某个顶点v出发,首先访问该顶点,然

图的遍历之深度优先搜索和广度优先搜索

转自:http://www.cnblogs.com/skywang12345/ 深度优先搜索的图文介绍 1. 深度优先搜索介绍 图的深度优先搜索(Depth First Search),和树的先序遍历比较类似. 它的思想:假设初始状态是图中所有顶点均未被访问,则从某个顶点v出发,首先访问该顶点,然后依次从它的各个未被访问的邻接点出发深度优先搜索遍历图,直至图中所有和v有路径相通的顶点都被访问到. 若此时尚有其他顶点未被访问到,则另选一个未被访问的顶点作起始点,重复上述过程,直至图中所有顶点都被访

图的遍历之深度优先搜索(DFS)

深度优先搜索(depth-first search)是对先序遍历(preorder traversal)的推广.”深度优先搜索“,顾名思义就是尽可能深的搜索一个图.想象你是身处一个迷宫的入口,迷宫中的路每一个拐点有一盏灯是亮着的,你的任务是将所有灯熄灭,按照DFS的做法如下: 1. 熄灭你当前所在的拐点的灯 2. 任选一条路向前(深处)走,每经过一个拐点将灯熄灭直到与之相邻的拐点的灯全部熄灭后,原路返回到某个拐点的相邻拐点灯是亮着的,走到灯亮的拐点,重复执行步骤1 3. 当所有灯熄灭时,结束 将

图的遍历之广度优先搜索(Breadth First Search)

描述 广度优先搜索算法(Breadth First Search)与树的层序遍历(level-order traversal)类似,基本思想是思想是: 从图中某顶点v出发,访问v之后,并将其访问标志置为已被访问,即visited[i]=1: 依次访问v的各个未曾访问过的邻接点: 分别从这些邻接点出发依次访问它们的邻接点,并使得"先被访问的顶点的邻接点先于后被访问的顶点的邻接点被访问,直至图中所有已被访问的顶点的邻接点都被访问到: 如果此时图中尚有顶点未被访问,则需要另选一个未曾被访问过的顶点作为

图的遍历之深度优先和广度优先

图的遍历之深度优先和广度优先 深度优先遍历 假设给定图G的初态是所有顶点均未曾访问过.在G中任选一顶点v为初始出发点(源点),则深度优先遍历可定义如下:首先访问出发点v,并将其标记为已访问过:然后依次从v出发搜索v的每个邻接点w.若w未曾访问过,则以w为新的出发点继续进行深度优先遍历,直至图中所有和源点v有路径相通的顶点(亦称为从源点可达的顶点)均已被访问为止.若此时图中仍有未访问的顶点,则另选一个尚未访问的顶点作为新的源点重复上述过程,直至图中所有顶点均已被访问为止. 图的深度优先遍历类似于树

41 蛤蟆的数据结构笔记之四十一图的遍历之深度优先

41  蛤蟆的数据结构笔记之四十一图的遍历之深度优先 本篇名言:"对于我来说 , 生命的意义在于设身处地替人着想 , 忧他人之忧 , 乐他人之乐. -- 爱因斯坦" 上篇我们实现了图的邻接多重表表示图,以及深度遍历和广度遍历的代码,这次我们先来看下图的深度遍历. 欢迎转载,转载请标明出处: 1.  原理 图遍历又称图的遍历,属于数据结构中的内容.指的是从图中的任一顶点出发,对图中的所有顶点访问一次且只访问一次.图的遍历操作和树的遍历操作功能相似.图的遍历是图的一种基本操作,图的许多其它

15 图-图的遍历-基于邻接矩阵实现的BFS与DFS算法

算法分析和具体步骤解说直接写在代码注释上了 TvT 没时间了等下还要去洗衣服 就先不赘述了 有不明白的欢迎留言交流!(估计是没人看的了) 直接上代码: 1 #include<stdio.h> 2 #include<queue> 3 #include<iostream> 4 using namespace std; 5 typedef struct{ 6 int Vex[10];//顶点表 7 int Edge[10][10]; 8 int vexnum,arcnum;

图的遍历(深度优先与广度优先搜索两种方案)

1.图的遍历--深度优先搜索 import java.util.Scanner ; public class Map{ static int n ; static int m ; static int[] book ; static int[][] e ; public static void mapDfs(int cur){ //深度优先搜索思想核心: System.out.print(cur + " ") ; for (int i=1;i<=n;i++) { if (e[cu

java实现图的遍历(深度优先遍历和广度优先遍历)

package arithmetic.graphTraveral;import java.util.LinkedList;import java.util.Queue; /** * 这个例子是图的遍历的两种方式 * 通过它,使我来理解图的遍历 * Created on 2013-11-18 * @version 0.1 */public class GraphTraveral{ // 邻接矩阵存储图 // --A B C D E F G H I // A 0 1 0 0 0 1 1 0 0 //