邻接表和邻接矩阵的创建 深度优先遍历和广度优先遍历
目录
一、实验目的及要求
1.理解带权图、邻接矩阵和邻接表的概念及其在图论中的应用。
2.掌握邻接矩阵和邻接表的创建与输出运算,理解它们的优缺点。
3.掌握深度优先遍历和广度优先遍历的递归算法,能够实现从顶点0开始的遍历。
二、实验内容
编写一个程序,设计带权图的邻接表和邻接矩阵的创建于输出运算,并在此基础上设计一个主程序:
(1)实现下页带权图的邻接矩阵与邻接表的创建与输出运算;
(2)实现从顶点0开始的深度优先遍历序列和广度优先遍历序列(递归算法)。
三、实验设备与环境
1.Windows 11
2.Codeblocks
四、实验设计方案
(一)实验步骤:
1.定义带权图的数据结构,包括顶点集、边集和权重集。
2.实现邻接矩阵的创建与输出运算。邻接矩阵是一个二维数组,表示图中顶点之间的连接关系和权重。创建一个函数来初始化邻接矩阵,并使用另一个函数输出邻接矩阵的内容。
3.实现邻接表的创建与输出运算。邻接表是一个链表结构,表示图中顶点之间的连接关系和权重。创建一个函数来初始化邻接表,并使用另一个函数输出邻接表的内容。
4.实现从顶点0开始的深度优先遍历序列和广度优先遍历序列的递归算法。编写两个函数,分别用于深度优先遍历和广度优先遍历,并从顶点0开始遍历图。
(二)设计思想:
1.邻接矩阵和邻接表是两种常见的图表示方法,各有优缺点。邻接矩阵的空间复杂度较高,但查询速度快;邻接表的空间复杂度较低,但查询速度慢。在实际应用中,应根据具体需求选择合适的表示方法。
2.深度优先遍历和广度优先遍历是两种常见的图遍历算法,可用于搜索、遍历或访问图中的节点。这两种算法在解决实际问题中有着广泛的应用,如拓扑排序、路径查找等。
3.在实现图的遍历算法时,递归是一种常用的方法。递归可以简化代码结构,提高代码的可读性和可维护性。同时,递归算法的时间复杂度较低,适合处理大规模的图数据。
(三)开发流程:
1.定义带权图的数据结构:使用结构体定义顶点、边和权重的数据类型,并使用数组或链表来表示顶点集、边集和权重集。
2.实现邻接矩阵的创建与输出运算:创建一个二维数组来表示邻接矩阵,使用函数初始化数组并填充初始值。编写一个函数来输出邻接矩阵的内容,可以使用循环遍历数组并输出每个元素的值。
3.实现邻接表的创建与输出运算:使用链表结构来表示邻接表,每个节点包含顶点和指向下一个节点的指针。创建一个函数来初始化邻接表,并使用另一个函数输出邻接表的内容。可以使用循环遍历链表并输出每个节点的信息。
4.实现深度优先遍历序列的递归算法:编写一个递归函数,从指定的起始顶点开始,依次访问相邻的顶点,并递归地调用自身来遍历其他相邻的顶点。在递归过程中记录访问的路径,最后返回路径序列。
5.实现广度优先遍历序列的递归算法:编写一个递归函数,创建一个队列来存储待访问的顶点,并将起始顶点入队。在循环中取出队首的顶点并访问它,然后将相邻的顶点入队。重复执行该过程直到队列为空,最后返回访问的路径序列。
五、实验结果
六、附录源码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define maxn 1024 //最大顶点数
int matrix[maxn][maxn]; //邻接矩阵
int n,m; //顶点数,边数
/*
边结点
*/
struct ArcNode{
int adjvex; //该边所指向的顶点的位置
int lowcost; //权值
ArcNode* next; //指向的下一条边的指针
};
ArcNode* ArcList[maxn*(maxn-1)]; //所有边结点
int in = 0; //下标
/*
顶点
*/
struct{
ArcNode* firstarc;
}AdjList[maxn];
/*
增加一条从i指向j的权值为k的顶点
*/
void add(int i,int j,int k){
matrix[i][j] = k;
ArcNode* p = new ArcNode();
p->adjvex = j; //它指向的是j顶点
p->lowcost = k; //权值为k
//p插入到链表头部
p->next = AdjList[i].firstarc;
AdjList[i].firstarc = p;
ArcList[in++] = p; //把这个边结点存储到数组中
}
int main() {
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
n = 6;
m = 10;
//初始化邻接矩阵
for(int i = 0;i<n;++i){
for(int j = 0;j<n;++j){
matrix[i][j] = -1;
}
}
//初始化AdjList
for(int i = 0;i<n;++i){
AdjList[i].firstarc = NULL;
}
//增加m条边
add(0,1,5);
add(0,3,3);
add(1,2,4);
add(2,0,8);
add(2,5,9);
add(3,2,5);
add(3,5,6);
add(4,3,5);
add(5,4,1);
add(5,0,3);
//打印邻接矩阵
cout << "adjacent matrix:" << endl;
for(int i = 0;i<n;++i){
for(int j = 0;j<n;++j){
cout << matrix[i][j] << " \n"[j == n-1];
}
}
//打印邻接表
cout << "adjacency list:" << endl;
ArcNode* p = 0;
for(int i = 0;i < n;++i){
p = AdjList[i].firstarc;
cout << i << " : ";
while(p){
cout << p->adjvex << "(" << p->lowcost << ")" << " -> ";
p = p->next;
}
cout << "^" << endl;
}
p = 0;
//销毁邻接表
for(int i = 0;i<in;++i){
delete ArcList[i]; //删除
ArcList[i] = 0; //指针置空
}
//修改每个顶点的firstarc为空
for(int i = 0;i<n;++i){
AdjList[i].firstarc = 0;
}
in = 0;
return 0;
}