數據結構與算法--圖的遍歷方式(深度遍歷和廣度遍歷)

數據結構與算法--圖的遍歷方式(深度遍歷和廣度遍歷)

1. 圖的深度優先遍歷

深度優先搜索算法:數據結構是棧。通過將頂點存入棧中,沿着路徑探索頂點,存在新的相鄰頂點就去訪問

鄰接矩陣深度遍歷思路:

1.將圖的頂點和邊的信息輸入到圖結構中
2.創建一個數組,用來標識頂點是否已經被遍歷過
3.初始化數組,將數組中元素置位 False
4.選擇頂點開始遍歷(注意非連通圖的情況)
5.進入遞歸,打印 i 對應的頂點信息,並將該頂點標識爲已遍歷
6.循環遍歷邊表,判斷當前邊表中兩個頂點是否有邊(arc[i][j] 是否等 1),並且當前頂點沒有遍歷過,則繼續遞歸遍歷

鄰接矩陣深度遍歷代碼實現:

// 深度優先
int visited[MAXVEX];  // 訪問標誌的數組
void DFS(MGraph G,int i){
    // ✅ 修改標誌
    visited[i] = TRUE;
    printf("%c",G.vers[i]);
    // ✅ 遞歸遍歷
    for (int j = 0; j <= G.numNodes; j++) {
        if (G.arc[i][j] == 1 && !visited[j]) {
            DFS(G, j);
        }
    }
}
void DFSTravese(MGraph G){
    // ✅ 初始化標誌數組
    for (int i = 0; i < G.numNodes; i++) {
        visited[i] = FALSE;
    }
    // ✅ 某一個頂點(防止非連通圖)
    for (int i = 0; i <= G.numNodes; i++) {
        // 判斷是否已經訪問
        if (!visited[i]) {
            DFS(G, i);
        }
    }
}

鄰接表深度遍歷代碼:

// 深度優先
int visited[MAXVEX];  // 訪問標誌的數組
void DFS(MGraph G,int i){
    // 修改標誌
    visited[i] = TRUE;
    
    EdgeNode *p;
    // 打印頂點 A
    printf("%c",G.adjlist[i].data);
    
    p = G.adjlist[i].firstedge;
    
    
    while (p) {
        if (!visited[p->adj_vex_index]) {
            DFS(G, p->adj_vex_index);
        }
        p = p->next;
    }
}

void DFSTravese(MGraph G){
    // 初始化標誌數組
    for (int i = 0; i < G.numNodes; i++) {
        visited[i] = FALSE;
    }
    // 某一個頂點(防止非連通圖)
    for (int i = 0; i <= G.numNodes; i++) {
        // 判斷是否已經訪問
        if (!visited[i]) {
            DFS(G, i);
        }
    }
}

2. 圖的廣度優先遍歷

廣度優先搜索算法:數據結構是隊列。通過將頂點存入隊列中,最先入隊列的頂點先被探索。

思路:
先把 圖 旋轉,看成樹
1.把根節點放到隊列的末尾
2.每次從隊列的頭部取出一個元素,檢測這個元素是否有下一級,有則全部放到隊尾
3.找到所有要找的元素是結束程序
4.如果遍歷整個樹還沒有找到,結束程序。


廣度優先遍歷,需要用到隊列,我們先定義隊列的方法

// 定義隊列
typedef struct {
    int data[MAXVEX];
    int front;
    int rear;
}Queue;
// 初始化
Status InitQueue(Queue *Q) {
    Q->front = 0;
    Q->rear = 0;
    return OK;
}
// 判斷空
Status QueueEmpty(Queue Q) {
    if (Q.front == Q.rear) {
        return TRUE;
    }
    return FALSE;
}

//入隊
Status EnQueue(Queue *Q, int e) {
    if ((Q->rear+1)%MAXVEX == Q->front) {
        return ERROR;
    }
    Q->data[Q->rear] = e;
    Q->rear = (Q->rear + 1)%MAXVEX;
    return OK;
}
// 出隊
Status DeQueue(Queue *Q, int *e) {
    if (Q->front == Q->rear)            /* 隊列空的判斷 */
    return ERROR;
    *e = Q->data[Q->front];
    Q->front = (Q->front+1)%MAXVEX;
    return OK;
}

鄰接矩陣廣度優先遍歷

int visited[MAXVEX]; /* 訪問標誌的數組 */
void BFSTraverse(MGraph G){

    Queue Q;
    InitQueue(&Q);
    
    // 將訪問標誌數組全部置爲"未訪問狀態FALSE"
    for (int i = 0 ; i < G.numVertexes; i++) {
        visited[i] = FALSE;
    }
    
    // 將訪問標誌數組全部置爲"未訪問狀態FALSE"
    for (int i = 0; i < G.numNodes; i++) {
        if (!visited[i]) {
            visited[i] = TRUE;
            printf("%c  ",G.vers[i]);
            
            // 入隊
            EnQueue(&Q, i);
            while (!QueueEmpty(Q)) {
                // 出隊
                DeQueue(&Q, &i);
                for (int j = 0; j < G.numNodes; j++) {
                    if (G.arc[i][j] == 1 && !visited[j]) {
                        visited[j] = TRUE;
                        printf("%c   ",G.vers[j]);
                        EnQueue(&Q, j);
                    }
                }
            }
        }
    }

}

鄰接表廣度優先遍歷

int visited[MAXSIZE]; /* 訪問標誌的數組 */
void BFSTraverse(GraphAdjList GL){
    
    //1.創建結點
    EdgeNode *p;
    
    Queue Q;
    InitQueue(&Q);
    

    //2.將訪問標誌數組全部置爲"未訪問狀態FALSE"
    for(int i = 0; i < GL->numVertexes; i++)
        visited[i] = FALSE;
    
    //3.對遍歷鄰接表中的每一個頂點(對於連通圖只會執行1次,這個循環是針對非連通圖)
    for(int i = 0 ;i < GL->numVertexes;i++){
        //4.判斷當前結點是否被訪問過.
        if(!visited[i]){
            visited[i] = TRUE;
            //打印頂點
            printf("%c ",GL->adjList[i].data);
            
            EnQueue(&Q, i);
            while (!QueueEmpty(Q)) {
                DeQueue(&Q, &i);
                p = GL->adjList[i].firstedge;
                while (p) {
                    //判斷
                    if(!visited[p->adjvex]){
                        visited[p->adjvex] = TRUE;
                         printf("%c ",GL->adjList[p->adjvex].data);
                        EnQueue(&Q, p->adjvex);
                    }
                    p = p->next;
                }
            }
            
        }
    }
    
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章