(二) 圖的遍歷

(二) 圖的遍歷

1. 深度優先搜索 (Depth First Search, DFS)

[外鏈圖片轉存失敗(img-MgjNKZTh-1567356455556)(C:\Users\alway\AppData\Roaming\Typora\typora-user-images\1567347155834.png)]

void DFS(Vertex v) {
	visited[v] = true;
    for (v的每個鄰接點w) {
        if(!visited[w]) {
            DFS(w);
        }
    }
}

**注:**可用stack改遞歸爲循環

**時間複雜度:**若有N個頂點,E條邊

  • 用鄰接表存儲圖, O(N+E)O(N+E)

  • 用鄰接矩陣存儲圖,O(N2)O(N^2)


2. 廣度優先搜索 (Breadth First Search, BFS)

[外鏈圖片轉存失敗(img-IjMMPRMt-1567356455557)(C:\Users\alway\AppData\Roaming\Typora\typora-user-images\1567347826519.png)]

void BFS(Vertex v) {
    visited[v] = true;
    Enqueue(v);
    while(!isEmpty(Q)) {
        v = Dequeue(Q);
        for (v的每個鄰接點w) {
            if(!visited[w]) {
                visited[w] = true;
                Enqueue(w, Q);
            }
        }
    }
}

**注:**使用隊列改遞歸爲循環

時間複雜度:(同上)


3. 圖不連通

**連通:**如果從v到w存在一條(無向)路徑,則稱v與w是連通的

**強連通:**如果從v到w存在雙向路徑,則稱v與w是強連通的

**路徑:**v到w的路徑是一系列頂點的集合,且任一對相鄰頂點間都有圖中的邊

**迴路:**起點等於終點的路徑

**連通圖:**圖中任意兩頂點均連通

連通分量:無向圖的極大連通子圖

  • 極大頂點數:再加一個就不連通了

  • 極大邊數:包含子圖中所有頂點相連的所有邊

    [外鏈圖片轉存失敗(img-hftgLg0I-1567356455559)(C:\Users\alway\AppData\Roaming\Typora\typora-user-images\1567348540093.png)]

void ListComponents(Graph G) {
	for (each v in G) {
        if (!visited[v]) {
            DFS(V);
        }
    }
}

**注:**每調用一次DFS(v)就把v所在的連通分量遍歷了一遍,BFS同理


4. 代碼實現

  • 鄰接表-DFS

/* 鄰接表存儲的圖 - DFS */
 
void Visit( Vertex V )
{
    printf("正在訪問頂點%d\n", V);
}
 
/* Visited[]爲全局變量,已經初始化爲false */
void DFS( LGraph Graph, Vertex V, void (*Visit)(Vertex) )
{   /* 以V爲出發點對鄰接表存儲的圖Graph進行DFS搜索 */
    PtrToAdjVNode W;
     
    Visit( V ); /* 訪問第V個頂點 */
    Visited[V] = true; /* 標記V已訪問 */
 
    for( W=Graph->G[V].FirstEdge; W; W=W->Next ) /* 對V的每個鄰接點W->AdjV */
        if ( !Visited[W->AdjV] )    /* 若W->AdjV未被訪問 */
            DFS( Graph, W->AdjV, Visit );    /* 則遞歸訪問之 */
}
  • 鄰接矩陣-BFS

/* 鄰接矩陣存儲的圖 - BFS */
 
/* IsEdge(Graph, V, W)檢查<V, W>是否圖Graph中的一條邊,即W是否V的鄰接點。  */
/* 此函數根據圖的不同類型要做不同的實現,關鍵取決於對不存在的邊的表示方法。*/
/* 例如對有權圖, 如果不存在的邊被初始化爲INFINITY, 則函數實現如下:         */
bool IsEdge( MGraph Graph, Vertex V, Vertex W )
{
    return Graph->G[V][W]<INFINITY ? true : false;
}
 
/* Visited[]爲全局變量,已經初始化爲false */
void BFS ( MGraph Graph, Vertex S, void (*Visit)(Vertex) )
{   /* 以S爲出發點對鄰接矩陣存儲的圖Graph進行BFS搜索 */
    Queue Q;     
    Vertex V, W;
 
    Q = CreateQueue( MaxSize ); /* 創建空隊列, MaxSize爲外部定義的常數 */
    /* 訪問頂點S:此處可根據具體訪問需要改寫 */
    Visit( S );
    Visited[S] = true; /* 標記S已訪問 */
    AddQ(Q, S); /* S入隊列 */
     
    while ( !IsEmpty(Q) ) {
        V = DeleteQ(Q);  /* 彈出V */
        for( W=0; W<Graph->Nv; W++ ) /* 對圖中的每個頂點W */
            /* 若W是V的鄰接點並且未訪問過 */
            if ( !Visited[W] && IsEdge(Graph, V, W) ) {
                /* 訪問頂點W */
                Visit( W );
                Visited[W] = true; /* 標記W已訪問 */
                AddQ(Q, W); /* W入隊列 */
            }
    } /* while結束*/
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章