深度优先搜索的过程类似于树的先序遍历

  1. 首先任意找一个未被遍历过的顶点,例如从 V1 开始,由于 V1 率先访问过了,所以,需要标记 V1 的状态为访问过;
  2. 然后遍历 V1 的邻接点,例如访问 V2 ,并做标记,然后访问 V2 的邻接点,例如 V4 (做标记),然后 V8 ,然后 V5 ;
  3. 当继续遍历 V5 的邻接点时,根据之前做的标记显示,所有邻接点都被访问过了。此时,从 V5 回退到 V8 ,看 V8 是否有未被访问过的邻接点,如果没有,继续回退到 V4 , V2 , V1 ;
  4. 通过查看 V1 ,找到一个未被访问过的顶点 V3 ,继续遍历,然后访问 V3  邻接点 V6 ,然后 V7 ;
  5. 由于 V7 没有未被访问的邻接点,所有回退到 V6 ,继续回退至 V3 ,最后到达 V1 ,发现没有未被访问的;
  6. 最后一步需要判断是否所有顶点都被访问,如果还有没被访问的,以未被访问的顶点为第一个顶点,继续依照上边的方式进行遍历。
  • 所谓深度优先搜索,是从图中的一个顶点出发,每次遍历当前访问顶点的临界点,一直到访问的顶点没有未被访问过的临界点为止。然后采用依次回退的方式,查看来的路上每一个顶点是否有其它未被访问的临界点。访问完成后,判断图中的顶点是否已经全部遍历完成,如果没有,以未访问的顶点为起始点,重复上述过程。
深度优先搜索是一个不断[回溯]的过程。
#include <stdio.h>
#include <stdlib.h>
#include <data.h>

#define MAX_VERTEX_NUM 20//最大顶点个数
#define VRType int //顶点间关系的变量类型
#define InfoType char //存储弧额外信息的指针
#define VertexType int //顶点数据类型

bool visited[MAX_VERTEX_NUM];//设置辅助数组,记录顶点是否被访问过

typedef struct 
{
    VRType adj;
    InfoType info;
}ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
typedef struct 
{
    VertexType vexs[MAX_VERTEX_NUM];
    AdjMatrix arcs;
    int vexnum,arcnum;
}MGraph;

//定位顶点在二维数组的位置
int LocateVex(MGraph *G,VertexType v)
{
    int i=0;
    for(;i<G->vexnum;i++)
    {
        if(G->vexs[i]==v)
        {
            break;
        }
    }
    if(i>=G->vexnum)
    {
        printf("此顶点不存在");
        return -1;
    }
    return i;
}
void CreateUDN(MGraph *G)
{
    scanf("%d%d",&(G->vexnum),&(G->arcnum));
    for(int i=0;i<G->vexnum;i++)
    {
        scanf("%d",&(G->vexs[i]));
    }
    for(int i=0;i<G->vexnum;i++)
    {
        for(int j=0;j<G->vexnum;j++)
        {
            G->arcs[i][j].adj=0;
            G->arcs[i][j].info=NULL;
        }
    }
    for(int k=0;k<G->arcnum;k++)
    {
        int v1,v2;
        int i=LocateVex(G,v1);
        int j=LocateVex(G,v2);
        if(i==-1||j==-1)
        {
            printf("此顶点不存在");
            return;
        }
        G->arcs[i][j].adj=1;
        G->arcs[j][i].adj=1;
    }
}

int FirstAdjVex(MGraph G,int v)//查找与顶点间有边的第一个顶点
{
    for(int i=0;i<G.vexnum;i++)
    {
        if(G.vexs[v][i])
        {
            return i;
        }
    }
    return -1;
}

int NextAdjVex(MGraph G,int v,int w)//从访问位置w的下一个位置开始,查找有边的点
{
    for(int i=w+1;i<G.vexnum;i++)
    {
        if(G.arcs[v][i].adj)
        {
            return i;
        }
    }
    return -1;
}

void visitVex(MGraph G,int v)
{
    printf("%d",G.vexs[v]);
}

void DFS(MGraph G,int v)
{
    visited[v]=true;
    visitVex(G,v);
    for(int w=FirstAdjVex(G,v);w>=0;w=NextAdjVex(G,v,w))
    {
        if(!visited[w])
        {
            DFS(G,w);
        }
    }
}

void DFSTraverse(MGraph G)
{
    int v;
    for(v=0;v<G.vexnum;v++)
    {
        visited[v]=false;
    }
    for(v=0;v<G.vexnum;v++)
    {
        if(!visited[v])
        {
            DFS(G,v);
        }
    }
}

int main()
{
    MGraph G;
    CreateUDN(&G);
    DFSTraverse(G);
    return 0;
}

无欲则刚
76 声望15 粉丝