12.1邻接表存储实现图的深度优先遍历

发布时间 2023-12-10 13:46:09作者: 艾鑫4646

掌握深度优先遍历

实验题目

邻接表存储实现图的深度优先遍历

设计文档

 代码

 #include<iostream>
using namespace std;
#define MVNum 100
typedef char OtherInfo;
int visited[MVNum]={0};  // visited数组,用于记录顶点是否被访问过

// 邻接表:顶点表、边表、邻接表
typedef struct ArcNode{
    int adjvex;  // 下标信息
    OtherInfo info;  // 其他信息
    struct ArcNode* next;
}ArcNode;

typedef struct VNode{
    char vex;  // 顶点信息
    ArcNode* first;  // 指向第一条边的指针
}VNode,AdjList[MVNum];

typedef struct{
    AdjList vertices;  // 邻接表数组
    int vexnum,arcnum;  // 顶点数和边数
}ALGraph;

// 定位顶点v在邻接表中的位置
int LocateVex(ALGraph G, char v){
    for(int i = 0; i < G.vexnum; ++i){
        if(G.vertices[i].vex == v)
            return i;
    }
    return -1;
}
 void CreatALGraph(ALGraph &G, int &err){
    cin >> G.vexnum >> G.arcnum;  // 输入顶点数和边数
    for(int i = 0; i < G.vexnum; ++i){  // 输入顶点信息,并初始化每个顶点的边表为空
        cin >> G.vertices[i].vex;
        G.vertices[i].first = NULL;
    }
    for(int k = 0; k < G.arcnum; ++k){  // 构建边表
        char v1, v2;
        cin >> v1 >> v2;
        int i, j;
        i = LocateVex(G, v1);
        j = LocateVex(G, v2);
        if(i == -1 || j == -1)
            err = 1;
        else{
            ArcNode* p1 = new ArcNode;  // 创建新的边节点
            p1->adjvex = j;
            p1->next = G.vertices[i].first;
            G.vertices[i].first = p1;
            ArcNode* p2 = new ArcNode;  // 创建新的边节点
            p2->adjvex = i;
            p2->next = G.vertices[j].first;
            G.vertices[j].first = p2;
        }
    }
}
 void DFS_ALGraph(ALGraph G, int adj){
    cout << G.vertices[adj].vex << " ";  // 输出当前顶点信息
    visited[adj] = 1;  // 标记该顶点已访问
    ArcNode* p = G.vertices[adj].first;  // 获取当前顶点的第一条边
    while(p != NULL){  // 遍历当前顶点的所有邻接点
        if(visited[p->adjvex] != 1)  // 如果邻接点未被访问,则递归访问
            DFS_ALGraph(G, p->adjvex);
        p = p->next;  // 移动到下一个邻接点
    }
}

int main(){
    ALGraph G;
    int err = 0;
    char star;
    CreatALGraph(G, err);  // 创建邻接表
    cin >> star;  // 输入起始顶点
    int adj = LocateVex(G, star);  // 定位起始顶点在邻接表中的位置
    if(adj == -1 || err == 1)
        cout << "error";
    else{
        DFS_ALGraph(G, adj);  // 开始深度优先遍历
    }
    return 0;
}

一、  个人体会(此部分与拼题a上主观题提交应一致)

 第一题

1、 实验中遇到的具体问题:

在实现这个程序时,我遇到了两个主要问题。首先,我需要理解邻接表如何用于图的表示。其次,我需要理解深度优先搜索遍历的原理和实现方法。

2、 问题如何解决的:

我首先定义了一个结构体来作为邻接表,然后通过输入的边的信息,将每个顶点与其相邻的顶点之间的关系记录在邻接表中。在深度优先搜索遍历中,当节点v的所在边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问为止。

3、 实验设计思路:

结构体定义:首先定义了一些结构体,包括ArcNode(边节点),VNode(顶点)和ALGraph(邻接表图)。边节点包含了一个邻接点(一个顶点)和其他信息。顶点包含了一个字符表示的顶点信息和一个指向第一条边的指针。邻接表图包含了一个顶点数组、一个边数组和一个邻接表数组,分别存储顶点信息、边信息和邻接表。

创建邻接表图:在CreatALGraph函数中,首先从标准输入中读取顶点数和边数。然后,为每个顶点输入一个字符表示的名称,并将每个顶点的边表初始化为空。接下来,你循环读取每条边的两个端点,并使用LocateVex函数找到这两个端点在邻接表中的位置。如果找不到任何一个端点,就设置错误标志。如果找到了,就使用"头插法"将一个新的边节点添加到这两个端点的边表中。

深度优先搜索:在DFS_ALGraph函数中,实现了深度优先搜索算法。从一个指定的邻接点开始,输出这个顶点的信息,并将这个顶点标记为已访问。然后,遍历这个顶点的所有邻接点。如果一个邻接点还没有被访问过,就递归地调用DFS_ALGraph函数对这个邻接点进行深度优先搜索。

主函数:在主函数中,创建了一个空的邻接表图,并调用CreatALGraph函数来填充这个图。然后,调用DFS_ALGraph函数来对图进行深度优先搜索遍历。

3、 实验后的感想:

在完成这个实验后,我对图的邻接表表示和深度优先搜索有了更深入的理解。邻接表是一种常用的图的表示方法,它通过使用数组和链表,有效地表示了图中顶点之间的关系。深度优先搜索则是一种用于遍历或搜索树或图的算法,它沿着树的深度遍历树的节点,尽可能深地搜索树的分支。在实验过程中,我遇到了一些困难,尤其是在构建邻接表和进行深度优先搜索时。我通过仔细阅读和理解代码,以及多次尝试和调试,最终成功地完成了实验。这个实验让我认识到编程需要细心和耐心,同时也需要不断地学习和实践。通过这个实验,我不仅学会了如何使用邻接表表示图,还学会了如何使用深度优先搜索遍历图。