数据结构实验6 :图的存储与遍历(邻接矩阵的深度优先遍历DFS和邻接表的广度优先遍历BFS)

这篇具有很好参考价值的文章主要介绍了数据结构实验6 :图的存储与遍历(邻接矩阵的深度优先遍历DFS和邻接表的广度优先遍历BFS)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

题目一

题目要求

利用邻接矩阵存储无向图,并从0号顶点开始进行深度优先遍历。

输入

输入第一行是两个整数n1 n2,其中n1表示顶点数(则顶点编号为0至n1-1),n2表示图中的边数。
之后有n2行输入,每行输入表示一条边,格式是“顶点1 顶点2”,把边插入图中。
例如:

4 4
0 1
1 3
0 3
0 2

输出

先输出存储图的邻接矩阵,同一行元素之间空1格,最后一个元素之后不要有空格。
之后空一行后输出从0号顶点开始的深度优先遍历序列,顶点编号之间空1格。
例如,对于上面的示例输入,输出为:

0 1 1 1
1 0 0 1
1 0 0 0
1 1 0 0
0 1 3 2

说明

输入第1个4表示有4个顶点,第2个4表示有4条边。之后的4行输入代表4条边的顶点。输出的前4行为邻接矩阵,之后空一行,然后输出的“0 1 3 2”是深度优先遍历序列。

代码实现

邻接矩阵图相关定义:

typedef int Vertex;
typedef int WeightType;
typedef struct EdgeNode {
    Vertex v1, v2;
}*Edge;
typedef struct MatrixGraphNode {
    int vertexNum; /* 顶点数 */
    int edgeNum; /* 边数 */
    WeightType** adjMatrix; /* 邻接矩阵 */
    int* visited; /* 标记数组,用来标记某一个点是否被访问过,DFS时要用到,也可以把它定义为全局变量,这里为了方便就写在结构体里 */
} *MatrixGraph;

邻接矩阵图的相关操作:

这里选择动态创建二维数组,因为不知道测试样例最大顶点数是多少。读者当然可以直接在定义结构体把就把adjMatrix定义为一个足够大的二维数组,而不必如此麻烦的动态创建。

MatrixGraph createMatrixGraph(int vertexNum) {
    MatrixGraph graph = (MatrixGraph)malloc(sizeof(struct MatrixGraphNode));
    graph->vertexNum = vertexNum;
    graph->edgeNum = 0;
    graph->visited = (int*)malloc(sizeof(int) * graph->vertexNum);
    /* 动态创建二维数组 */
    graph->adjMatrix = (WeightType**)malloc(sizeof(WeightType*) * graph->vertexNum);
    for (int i = 0;i < graph->vertexNum;i++)
        graph->adjMatrix[i] = (WeightType*)malloc(sizeof(WeightType) * graph->vertexNum);
    /* 初始化邻接矩阵adjMatrix和标记数组visited */
    for (int i = 0;i < graph->vertexNum;i++) {
        graph->visited[i] = 0;
        for (int j = 0;j < graph->vertexNum;j++)
            graph->adjMatrix[i][j] = 0;
    }
    return graph;
}
void insertEdge(MatrixGraph graph, Edge edge) {
    graph->adjMatrix[edge->v1][edge->v2] = 1;
    graph->adjMatrix[edge->v2][edge->v1] = 1;
}
MatrixGraph buildMatrixGraph() {
    Edge edge = (Edge)malloc(sizeof(struct EdgeNode));
    int vertexNum;
    scanf("%d", &vertexNum);
    MatrixGraph graph = createMatrixGraph(vertexNum);
    scanf("%d", &graph->edgeNum);
    for (int i = 0;i < graph->edgeNum;i++) {
        scanf("%d%d", &edge->v1, &edge->v2);
        insertEdge(graph, edge);
    }
    return graph;
}

深度优先搜索DFS和打印邻接矩阵图

void DFS(MatrixGraph graph, Vertex v) {
	/* 访问当前顶点 */
    printf("%d ", v);
    graph->visited[v] = 1;
    for (int i = 0;i < graph->vertexNum;i++)
    	/* 如果w没有被访问且和v相连,就递归地访问它 */
        if (!graph->visited[i] && isEdge(graph, v, i))
            DFS(graph, i);
}
void printGraph(MatrixGraph graph) {
    for (int i = 0;i < graph->vertexNum;i++)
        for (int j = 0;j < graph->vertexNum;j++)
            j == graph->vertexNum - 1 ? printf("%d\n", graph->adjMatrix[i][j]) : printf("%d ", graph->adjMatrix[i][j]);
}

主函数

int main() {
    MatrixGraph graph = buildMatrixGraph();
    printGraph(graph);
    DFS(graph, 0);
    system("pause");
    return 0;
}

运行结果

数据结构实验6 :图的存储与遍历(邻接矩阵的深度优先遍历DFS和邻接表的广度优先遍历BFS)

题目二

题目要求

利用邻接表存储无向图,并从0号顶点开始进行广度优先遍历。

输入

输入第一行是两个整数n1 n2,其中n1表示顶点数(则顶点编号为0至n1-1),n2表示图中的边数。
之后有n2行输入,每行输入表示一条边,格式是“顶点1 顶点2”,把边插入图中。在链表中插入元素时,在链表头部插入。需要注意,由于是无向图,因此同一条边需要在两条链表中都插入。
例如:

4 4
0 1
1 3
0 3
0 2

输出

先按0至n1-1输出存储图的邻接表,每个链表占1行,同一行元素之间空1格,最后一个元素之后不要有空格。先输出顶点编号,之后按链表顺序输出相邻顶点编号。
之后空一行后输出从0号顶点开始的广度优先遍历序列,顶点编号之间空1格。
例如,对于上面的示例输入,输出为:

0 2 3 1
1 3 0
2 0
3 0 1
0 2 3 1

说明

输入第1个4表示有4个顶点,第2个4表示有4条边。之后的4行输入代表4条边的顶点。输出前4行为邻接表中的4个链表,之后空一行,然后输出的“0 2 3 1”是深度优先遍历序列。

代码实现

邻接表相关定义

typedef int Vertex;
/* 边 */
typedef struct EdgeNode {
    Vertex v1, v2;
}*Edge;
/* 邻接点 */
typedef struct AdjVNode {
    Vertex adjVertex;
    struct AdjVNode* next;
}*AdjVNodePtr;
/* 邻接表头节点 */
typedef struct VertexNode {
    AdjVNodePtr firstEdge;
}*AdjList;
/* 邻接表图 */
typedef struct ListGraphNode {
    int vertexNum;
    int edgeNum;
    AdjList adjList;
    int* visited;
}*ListGraph;

图的相关操作

ListGraph createListGraph(int vertexNum) {
    ListGraph graph = (ListGraph)malloc(sizeof(struct ListGraphNode));
    graph->vertexNum = vertexNum;
    graph->edgeNum = 0;
    graph->visited = (int*)malloc(sizeof(int));
    graph->adjList = (AdjList)malloc(sizeof(struct VertexNode) * graph->vertexNum);
    /* 初始化邻接表和标记数组 */
    for (int i = 0;i < graph->vertexNum;i++) {
        graph->adjList[i].firstEdge = NULL;
        graph->visited[i] = 0;
    }
    return graph;
}
void insertEdge(ListGraph graph, Edge edge) {
	/* 插入边<v1,v2> */
    AdjVNodePtr newNode = (AdjVNodePtr)malloc(sizeof(struct AdjVNode));
    newNode->adjVertex = edge->v2;
    newNode->next = graph->adjList[edge->v1].firstEdge;
    graph->adjList[edge->v1].firstEdge = newNode;
	/* 插入边<v2,v1> */
    newNode = (AdjVNodePtr)malloc(sizeof(struct AdjVNode));
    newNode->adjVertex = edge->v1;
    newNode->next = graph->adjList[edge->v2].firstEdge;
    graph->adjList[edge->v2].firstEdge = newNode;
}
ListGraph buildListGraph() {
    Edge edge = (Edge)malloc(sizeof(struct EdgeNode));
    int vertexNum;
    scanf("%d", &vertexNum);
    ListGraph graph = createListGraph(vertexNum);
    scanf("%d", &graph->edgeNum);
    for (int i = 0;i < graph->edgeNum;i++) {
        scanf("%d%d", &edge->v1, &edge->v2);
        insertEdge(graph, edge);
    }
    return graph;
}

深度优先搜索BFS和打印邻接表图

/* 队列及相关操作 */
typedef struct QueueNode {
    int* data;
    int front, rear;
    int maxSize;
}*Queue;
Queue createQueue(int maxSize) {
    Queue queue = (Queue)malloc(sizeof(struct QueueNode));
    queue->maxSize = maxSize;
    queue->data = (int*)malloc(sizeof(int) * queue->maxSize);
    queue->front = queue->rear = 0;
    return queue;
}
int isFull(Queue queue) {
    return queue->front == (queue->rear + 1) % queue->maxSize;
}
int isEmpty(Queue queue) {
    return queue->front == queue->rear;
}
void addQueue(Queue queue, int data) {
    if (isFull(queue))
        return;
    queue->data[queue->rear] = data;
    queue->rear = (queue->rear + 1) % queue->maxSize;
}
int deleteQueue(Queue queue) {
    if (isEmpty(queue))
        return -1;
    int data = queue->data[queue->front];
    queue->front = (queue->front + 1) % queue->maxSize;
    return data;
}
/* 深度优先搜索 */
void BFS(ListGraph graph, Vertex start) {
    Queue queue = createQueue(graph->vertexNum);
    printf("%d ", start);
    graph->visited[start] = 1;
    addQueue(queue, start);
    Vertex v;
    while (!isEmpty(queue)) {
        v = deleteQueue(queue);
        for (AdjVNodePtr w = graph->adjList[v].firstEdge;w;w = w->next) {
            if (!graph->visited[w->adjVertex]) {
                printf("%d ", w->adjVertex);
                graph->visited[w->adjVertex] = 1;
                addQueue(queue, w->adjVertex);
            }
        }
    }
}
/* 打印图 */
void printGraph(ListGraph graph) {
    for (int i = 0;i < graph->vertexNum;i++) {
        printf("%d ", i);
        for (AdjVNodePtr w = graph->adjList[i].firstEdge;w;w = w->next)
            w->next == NULL ? printf("%d\n", w->adjVertex) : printf("%d ", w->adjVertex);
    }
}

主函数

int main() {
    ListGraph graph = buildListGraph();
    printGraph(graph);
    BFS(graph, 0);
    system("pause");
    return 0;
}

运行结果图

数据结构实验6 :图的存储与遍历(邻接矩阵的深度优先遍历DFS和邻接表的广度优先遍历BFS)文章来源地址https://www.toymoban.com/news/detail-487758.html

到了这里,关于数据结构实验6 :图的存储与遍历(邻接矩阵的深度优先遍历DFS和邻接表的广度优先遍历BFS)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 24考研数据结构-图的存储结构邻接矩阵

    【1】顶点的结点结构 ——————— | data | firstarc | ——————— data数据域:储存顶点vi firstarc链域:指向链表中第一个结点 【2】弧的结点结构 —————————— | adjvex | info | nextarc | —————————— adjvex邻接点域:与顶点vi邻接的点在图中的位置 info数据域

    2024年02月14日
    浏览(41)
  • 数据结构--图的存储邻接表法

    邻接矩阵: 数组实现的顺序存储,空间复杂度高,不适合存储稀疏图 邻接表: 顺序+链式存储 无向图: 边结点的数量是 2|E|, 整体空间复杂度为 O(|V| + 2|E|) 有向图: 边结点的数量是 |E|, 整体空间复杂度为 O(|V| + |E|) 图的邻接表表示方式并不唯一 color{red}图的邻接表表示方

    2024年02月16日
    浏览(29)
  • C++数据结构之图的存储结构——邻接矩阵和邻接表实现无向图

    关键点: 1.构建二维数组 2.对应边的位置赋值为1 由于比较简单就直接上代码: 个人对邻接表实现无向图的理解如下,仅供参考:         由于无向图的组成是由多个顶点和多条无向边组成的,因此我们可以把它拆分成两个结构,分别是顶点和无向边,又由于我们是使用

    2024年02月05日
    浏览(39)
  • 图的数据结构,系统学习图的基本概念、定义和建立,学会邻接矩阵、邻接表以及实现六度空间案例,遍历图的方式——广度、深度访问

    图 :G = (V,E) Graph = (Vertex, Edge) V:顶点(数据元素)的有穷非空集合; E:边的有穷集合。 有向图 :每条边都是有方向的     无向图 :每条边都是无方向的   完全图 :任意两点之间都有一条边相连    无向完全图:n个顶点,n(n-1)/2条边 无向完全图:n个顶点,n(n-1)条边 稀疏

    2023年04月22日
    浏览(30)
  • 数据结构--5.1图的存储结构(十字链表、邻接多重表、边集数组)

    目录 一、十字链表(Orthogonal List) 二、邻接多重表 三、边集数组 四、深度优先遍历   重新定义顶点表结点结构:  data firstIn firstOut 重新定义边表结构结点: tailVex headVex headLink tailLink        十字链表的好处就是因为把邻接表和逆邻接表整合在了一起,这样既容易找到Vi为

    2024年02月10日
    浏览(28)
  • 【数据结构】图的存储与遍历

    图是由顶点集合及顶点间的关系组成的一种数据结构:G = (V, E) 在有向图中,顶点对x, y是有序的,顶点对x,y称为顶点x到顶点y的一条边(弧),x, y和y, x是两条不同的边。 在无向图中,顶点对(x, y)是无序的,顶点对(x,y)称为顶点x和顶点y相关联的一条边,这条边没有特定方向,

    2024年02月22日
    浏览(31)
  • 【数据结构】图的定义,存储,遍历

    🎊专栏【数据结构】 🍔喜欢的诗句:更喜岷山千里雪 三军过后尽开颜。 🎆音乐分享【Dream It Possible】 大一同学小吉,欢迎并且感谢大家指出我的问题🥰 目录 🍔前言 🎁图的定义   🏳️‍🌈有向完全图 🏳️‍🌈无向完全图 🎁存储结构 🏳️‍🌈邻接矩阵  🎈代码

    2024年02月06日
    浏览(62)
  • 数据结构上机实验——图的实现(以无向邻接表为例)、图的深度优先搜索(DFS)、图的广度优先搜索(BFS)

      图采用邻接表存储结构,编程实现图的深度优先搜索和广度优先搜索算法。              2.1创建图 2.1.1定义图的顶点、边及类定义   我们定义一个 邻接表类(ALGraph) 。这里实现一些基础的数据结构。要注意结构体的嵌套。    Edge: 用于表示图中的边

    2024年02月04日
    浏览(34)
  • 《数据结构》实验报告六:图的表示与遍历

    1、掌握图的 邻接矩阵 和 邻接表 表示 2、掌握图的 深度优先 和 广度优先 搜索方法 3、理解 图的应用 方法 说明以下概念 1、深度优先搜索遍历:        一种图的遍历方式:从图中 任意一个 起始顶点 V 出发,接着访问它的任意一个 邻接顶点 W1 ;再从 W1 出发,访问与 W1

    2024年02月06日
    浏览(48)
  • 图的邻接矩阵存储及遍历操作

    任务描述 本关任务:要求从文件输入顶点和边数据,包括顶点信息、边、权值等,编写程序实现以下功能。 1)构造无向网G的邻接矩阵和顶点集,即图的存储结构为邻接矩阵。 2)输出无向网G的各顶点和邻接矩阵。 3)输出无向网G中顶点H的所有邻接顶点。 测试说明 平台会对

    2024年02月06日
    浏览(26)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包