1. 深度优先遍历
深度优先遍历也称为,深度优先搜索,简称为DFS。会先从一个顶点开始,找到其未被访问的邻接点出发,直至所有的顶点都被访问,其实深度优先是一个递归的过程。

- 邻接矩阵的深度优先遍历
实现思路:
1、  将图的顶点和边信息保存在图结构中
2、  创建一个visited数组,用来标识顶点是否被遍历过
3、  初始化visited数组,将数组元素置为FALSE
4、  选择任意顶点开始遍历
5、  进入递归,visited中标记该顶点为已遍历
6、  循环遍历边表,判断当前arc[i][j]是否等于1,并且当前顶点没有被遍历过,继续进行递归
// DFS遍历
Boolean visited[MAXVEX]; // 访问标志的数组 ,用来记录顶点是否被访问过
/**
 1.标识顶点是否被标记过
 2.选择从某一个顶点开始(非连通图的情况)
 3.进入递归,打印i点信息
 4.[i][j]是否为1,
 */
void DFS(MGraph G,int i){
    //首先把顶点的标记已经访问
    visited[i] = TRUE;
    printf("%c",G.vexs[i]);
    //从0到所有的节点 遍历看是否与当前节点是否有关系
    for (int j = 0; j<G.numVertexes; j++) {
        /*
         G.arc[i][j] == 1 与当前节点存在连接关系
         是否已经被访问
         */
        if (G.arc[i][j] == 1 && !visited[j]) {
            DFS(G, j); // 对访问的邻接顶点递归调用
        }
    }
}
// 邻接矩阵的深度遍历操作
void DFSTravese(MGraph G){
    //1.初始化 开始遍历时所有顶点的标记都为FALSE
    for (int i = 0; i<G.numVertexes; i++) {
        visited[i] = FALSE;
    }
    // for循环可以保证在非连通图的情况下,所有的顶点也能遍历到
    for (int i = 0; i<G.numVertexes; i++) { 
        // 没有访问 才可以进行深度遍历
        if (!visited[i]) {
            DFS(G, i);
        }
    }
}
- 邻接表的深度优先遍历
实现思路:
1、   利利⽤用邻接矩阵将信息存储到邻接表中
2、   创建⼀一个visited 数组,⽤来标识顶点是否已经被遍历过.
3、   初始化visited 数组,将数组中元素置为FALSE
4、   选择顶点开始遍历.(注意⾮非连通图的情况)
5、   进⼊入递归; 打印i 对应的顶点信息. 并将该顶点标识为已遍历.
6、   循环遍历边表,判断当前顶点 是否等于1,并且当前该顶点没有被遍历过,则继续递归 DFS;

Boolean visited[MAXSIZE]; /* 访问标志的数组 */
/* 邻接表的深度优先递归算法 */
void DFS(GraphAdjList GL, int i){
    EdgeNode *p;
    visited[i] = TRUE;
    //打印顶点数据
    printf("%c ",GL->adjList[i].data);
    p = GL->adjList[i].firstedge;
    while (p) {
        // 判断p的adjvex对应的顶点表的下标
        if (!visited[p->adjvex]) {
            DFS(GL, p->adjvex);  // 找到未被访问的顶点,继续递归遍历
        }
        p = p->next; // 如果被访问的话,找到下一个
    }
}
/* 邻接表的深度遍历操作 */
void DFSTraverse(GraphAdjList GL)
{
    //1. 将访问记录数组默认置为FALSE
    for (int i = 0; i < GL->numVertexes; i++) {
        /*初始化所有顶点状态都是未访问过的状态*/
        visited[i] = FALSE;
    }
    //2. 选择一个顶点开始DFS遍历. 例如A
    for(int i = 0; i < GL->numVertexes; i++)
        //对未访问过的顶点调用DFS, 若是连通图则只会执行一次.
        if(!visited[i])
            DFS(GL, i);
}
2. 广度优先遍历
广度优先遍历又称为广度优先搜索,简称BFS。
如果说图的深度优先遍历类似树的前序遍历,那么图的广度优先遍历就类似于树的层序遍历。稍稍变形如下。

广度优先遍历的实现:
1、  把根节点放到队列列的末尾。
2、  每次从队列列的头部取出⼀一个元素,查看这个元素所有的下⼀一级元素,把它们放到队列的末尾,并把这个元素记为下一级元素的前驱
3、  找到所要找的元素时结束程序。
4、  如果遍历整个树还没有找到,结束程序.

- 邻接矩阵的广度优先遍历
Boolean visited[MAXVEX]; /* 访问标志的数组 */
void BFSTraverse(MGraph G){
    Queue Q;
    InitQueue(&Q);
    //将访问标识数组置为未访问状态
    for (int i = 0 ; i < G.numVertexes; i++) {
        visited[i] = FALSE;
    }
    // 遍历所有的顶点,这个循环是针对非连通图,对于连通图只会执行1次
    for (int i = 0; i<G.numVertexes; i++) {
        if (!visited[i]) {
            visited[i] = TRUE;
            printf("%c ",G.vexs[i]);
            // 入队
            EnQueue(&Q, i);
            while (!QueueEmpty(Q)) {
                // 出队
                DeQueue(&Q, &i);
                for (int j = 0; j<G.numVertexes; j++) {
                    // 找到下一级别的顶点,将其入栈
                    if (G.arc[i][j] == 1 && !visited[j]) {
                        visited[j] = TRUE;
                        printf("%c ",G.vexs[j]);
                        EnQueue(&Q, j);
                    }
                }
            }
        }
    }
}
- 邻接表的广度优先遍历
Boolean visited[MAXSIZE];
void BFSTraverse(GraphAdjList GL){
    // 创建结点
    EdgeNode *p;
    Queue Q;
    InitQueue(&Q);
    // 将访问标识数组置为未访问状态
    for(int i = 0; i < GL->numVertexes; i++){
        visited[i] = FALSE;
    }
    // 遍历所有的顶点,这个循环是针对非连通图,对于连通图只会执行1次
    for (int i = 0; i<GL->numVertexes; i++) {
        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;
                }
            }
        }
    }
}