圖算法之DFS

深度優先搜索(Depth  First Search),相似於樹的前序遍歷,搜索模型是棧,運用的是遞歸思想,如下面的無向圖爲例:html

DFSBFS_thumb_thumb

 

僞代碼實現以下:shell

其中u 爲 v 的先輩或父母。ubuntu


DFS(G)spa

 for each vertex u ∈ V [G]
       do color[u] ← WHITE
          π[u] ← NIL //第1-3行,把全部頂點置爲白色,全部π 域被初始化爲NIL。
 time ← 0       //復位時間計數器
 for each vertex u ∈ V [G]
       do if color[u] = WHITE
             then DFS-VISIT(u)  //調用DFS-VISIT訪問u,u成爲深度優先森林中一棵新的樹
    //第5-7行,依次檢索V中的頂點,發現白色頂點時,調用DFS-VISIT訪問該頂點。每一個頂點u 都對應於一個發現時刻d[u]和一個完成時刻f[u]。

 

DFS-VISIT(u)code

color[u] ← GRAY           
time ← time +1             
d[u] ← time                   //記錄u被發現的時間
for each v ∈ Adj[u]   //檢查並訪問 u 的每個鄰接點 v
       do if color[v] = WHITE            //若是v 爲白色,則遞歸訪問v。
             then π[v] ← u                   //置u爲 v的先輩
                    DFS-VISIT(v)        
color[u] ← BLACK         //u 置爲黑色,表示u及其鄰接點都已訪問完成
f [u] ← time ← time +1  //訪問完成時間記錄在f[u]中。

實驗環境爲ubuntu14.04 x86htm

  鄰接表實現:blog

#include <stdio.h>
#include <malloc.h>

#define MAX_VERTEX_NUM 50 

typedef char vertexType;
typedef int edgeType;

/* 邊表 */
typedef struct ArcNode
{
    int adjIndex;
    ArcNode *nextArc;  
    edgeType weight;
}ArcNode;

/* 頂點表 */
typedef struct VNode
{
    vertexType data;
    ArcNode *firstArc;
}VNode, AdjList[MAX_VERTEX_NUM];

/* 圖結構 */
typedef struct
{
    AdjList adjList;
    int vexNum;
    int edgeNum;
}ALGraph;

int visit[MAX_VERTEX_NUM] = {0};

void DFS(ALGraph *G, int i)
{
    visit[i] = 1;

    printf("%c ", G->adjList[i].data);

    ArcNode *arcNodePt = G->adjList[i].firstArc;
    while (arcNodePt)
    {
        if (!visit[arcNodePt->adjIndex])
        {
            DFS(G, arcNodePt->adjIndex);
        }
        arcNodePt = arcNodePt->nextArc;
    }
    // printf("recursion back\n");
}

void DFSTraverse(ALGraph *G)
{
    int i;

    // for (i = 0; i < G->vexNum; i++)
    // {
    //     visit[i] = 0;
    // }

    for (i = 0; i < G->vexNum; i++)
    {
        if (!visit[i])
        {
            DFS(G, i);
        }
    }
}

void CreateALGraph(ALGraph *G)
{
    int i, j, k;
    ArcNode *e;
    int c;

    printf("輸入頂點數和邊數:\n");
    scanf("%d %d", &G->vexNum, &G->edgeNum);
    setbuf(stdin, NULL);

    for (i = 0; i < G->vexNum; i++)
    {
        printf("輸入頂點信息:\n");
        scanf("%c", &G->adjList[i].data);
        G->adjList[i].firstArc = NULL;

        while((c = getchar()) != '\n' && c != EOF);
    }

    for (k = 0; k < G->edgeNum; k++)
    {
        printf("輸入邊(vi,vj)的頂點序號i,j:\n");
        scanf("%d %d", &i, &j);

        while((c = getchar()) != '\n' && c != EOF);
        
        e = (ArcNode*)malloc(sizeof(ArcNode));
        if (NULL == e)
        {
            return;
        }

        e->adjIndex = j;
        e->nextArc = G->adjList[i].firstArc;
        G->adjList[i].firstArc = e;

        // double direction copy
        e = (ArcNode *)malloc(sizeof(ArcNode));
        if (NULL == e)
        {
            return;
        }
        e->adjIndex = i;
        e->nextArc = G->adjList[j].firstArc;
        G->adjList[j].firstArc = e;
    }
}

int main(int argc, char const *argv[])
{
    ALGraph G;    
    CreateALGraph(&G);

    DFSTraverse(&G);
    return 0;
}

 

運行結果: A F G H E D I C B (與輸入順序有關)
 
鄰接矩陣實現:
#include <stdio.h>
#include <malloc.h>

#define MAX_VERTEX_NUM 50 

typedef char vertexType;
typedef int edgeType;

typedef struct
{
    vertexType vexs[MAX_VERTEX_NUM];
    edgeType arc[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
    int vexNum;
    int edgeNum;
}Graph;

int visit[MAX_VERTEX_NUM] = {0};

void CreateALGraph(Graph *G)
{
    int i, j, k;
    int c;

    printf("輸入頂點數和邊數:\n");
    scanf("%d %d", &G->vexNum, &G->edgeNum);
    setbuf(stdin, NULL);

    for (i = 0; i < G->vexNum; i++)
    {
        printf("輸入第%d個頂點信息:\n", i + 1);
        scanf("%c", &G->vexs[i]);

        while((c = getchar()) != '\n' && c != EOF);
    }

    for (i = 0; i < G->vexNum; i++)
    {
        for (j = 0; j < G->vexNum; j++)
        {
            G->arc[i][j] = 0;
        }
    }


    for (k = 0; k < G->edgeNum; k++)
    {
        printf("輸入邊(vi,vj)的下標i,j:\n");
        scanf("%d %d", &i, &j);

        while((c = getchar()) != '\n' && c != EOF);

        // set a default weight
        G->arc[i][j] = G->arc[j][i] = 1;   
    }
}

void DFS(Graph G, int i)
{
    visit[i] = 1;
    printf("%c ", G.vexs[i]);

    for (int j = 0; j < G.vexNum; j++)
    {
        if (G.arc[i][j] == 1 && !visit[j])
        {
            DFS(G, j);
        }
    }
}

void DFSTraverse(Graph G)
{
    for (int i = 0; i < G.vexNum; i++)
    {
        if (!visit[i])
        {
            DFS(G, i);
        }
    }
}

int main(int argc, char const *argv[])
{
    Graph G;    
    CreateALGraph(&G);

    DFSTraverse(G);
    return 0;
}
運行結果: A B C D E F G H I
相關文章
相關標籤/搜索