logo资料库

北邮 数据结构第三次实验 图 实验报告.doc

第1页 / 共16页
第2页 / 共16页
第3页 / 共16页
第4页 / 共16页
第5页 / 共16页
第6页 / 共16页
第7页 / 共16页
第8页 / 共16页
资料共16页,剩余部分请下载后查看
北京邮电大学信息与通信工程学院 数据结构实验报告 实验名称: 实验三——图 学生姓名: 班 级: 班内序号: 学 日 号: 期: 2017 年 12 月 23 日 1. 实验要求 根据图的抽象数据类型的定义,使用邻接矩阵或邻接表实现一个图。 图的基本功能: 1、图的建立 2、图的销毁 3、深度优先遍历图 4、广度优先遍历图 5、使用普里姆算法生成最小生成树 6、使用克鲁斯卡尔算法生成最小生成树 7、求指定顶点到其他各顶点的最短路径 编写测试 main()函数测试图的正确性 思考问题(选作): 1、若测试数据量较大,如何使得栈不溢出?使用非递归方式编写新的深度优先遍历 函数。提示:可以使用 STL 中的 stack 来辅助实现。 2、最短路径 D 算法,是否可以优化?请写出优化的思路并计算时间复杂度,同时实 现一个新的优化的最短路径算法。 2. 程序分析 2.1 存储结构 第 1页
北京邮电大学信息与通信工程学院 邻接矩阵:可以使用二维数组表示顶点之间相邻关系。 用邻接矩阵表示法表示图,除了存储用于表示顶点间相邻关系的邻接矩阵外,通常还要 用一个顺序表来存储顶点信息 2.2 关键算法分析 1:邻接矩阵的建立 a:初始化顶点:vertex[k] = a[k]; b:初始化边:arcs[k][j] = 0; c:输入边的权值:cin >> data; arcs[i][j] = data; d:矩阵对称:arcs[j][i] = arcs[i][j]; 时间复杂度:O(n2) 2:深度优先遍历 a:初始状态,结点均未被访问:bool visited[MAXSIZE]={false}; b:从结点 v 开始访问:visited[v]=true; c:连通图:for (int j=0;j
北京邮电大学信息与通信工程学院 3:广度优先遍历 a:初始状态,结点均未被访问:bool visited[MAXSIZE]={false}; b:从结点 v 开始访问:visited[v]=true; c:v 入队:quene[++r] = v; d:队头元素出队:v = quene[++f]; e:打印出队元素:cout << vertex[v]; f:新元素入队:if (arc[v][j])!=0&&!visited[j]) 时间复杂度:O(n) 空间复杂度:O(n) quene[++r] = j; 第 3页
北京邮电大学信息与通信工程学院 4:普里姆算法 a:初始化辅助数组:adjvex[i] = 0; lowcost[i] = G.arcs[0][i]; b:通过函数,求辅助数组最小值:int k = mininum(G, lowcost); c:打印此条路径:cout << 'V' << adjvex[k] << "->V" << k << endl; e:判断新结点各边权值的条件:if (lowcost[j] != 0 && G.arcs[k][j] < lowcost[j]) f:满足条件则更新辅助数组:lowcost[j] = G.arcs[k][j]; adjvex[j] = k; 时间复杂度:O(n2) 第 4页
北京邮电大学信息与通信工程学院 5:克鲁斯卡尔算法 a:获取 EdgeList,并对其排序:A.GenSortEdge(A, Edgelist); b:判断两个顶点的连接边是否构成回路:if (sn1 != sn2) c:构成回路后打印路径:cout << 'V' << m << "->V" << l << endl; d:将集合编号 sn2 的更新为 sn1:if (vset[i] == sn2) vset[i] = sn1; 时间复杂度:O(n2) 第 5页
北京邮电大学信息与通信工程学院 6: Dijkstra 算法 a:初始化辅助数组:Disk[i] = G.arcs[v][i]; if (Disk[i] != MAXSIZE) P[i] = v; else P[i] = -1; b:寻找离 v0 最近的顶点:if ((v = FindMin(Disk, S, G.vNum)) == -1) 第 6页
北京邮电大学信息与通信工程学院 c:更新辅助数组:Disk[j] = G.arcs[v][j] + Disk[v]; P[j] = v; d:打印路径:Print(Disk, P, G.vNum); 时间复杂度:O(n2) 2.3 其他 3. 程序运行结果 1、 测试主函数流程: 开始 循环输入边和权值 输入遍历起点 深度优先遍历 广度优先遍历 普里姆算法 最小生成树 克鲁斯卡尔算法 最小生成树 输入求最短 路径的起点 输出最短路径 结束 第 7页
北京邮电大学信息与通信工程学院 2、 测试条件:设置五个顶点:char a[5] = { 'A','B','C','D','E' },然后假设有 7 条 边 int sides = 7。通过循环,分别输入每条边的两个顶点以及该边的权值, 然后输入遍历的起始点下标,依次打印出深度优先遍历,广度优先遍历, 普里姆最小生成树路径和克鲁斯卡尔最小生成树路径。最后,通过输入起 始点,分别生成各点到起始点的最短路径。最后,结束程序。 3、 测试结论: 4. 总结 1、 调试时出现的问题及解决的方法: 书上的代码有很多小问题,包括 if 条件语句的判定有些小问题,或者前后命名 的不统一导致报错之类的。并且,书上的各个函数是没有写到类的 public 里面 的,导致很多时候访问的时候回报错。改进后,将各个函数写进了 public 里面, 然后对 if 条件语句的判定条件进行了一些修改,将命名进行了统一后,调试成 功。 2、 心得体会: 图这一部分,是很难的一部分。尤其是难在对代码的理解上面。普里姆算法, 克鲁斯卡尔算法以及最短路径的算法,每一个算法都包含了许多辅助数组或者 一些其他的函数来帮助运算,理解起来不容易。不过认真完成本次实验后,发 第 8页
分享到:
收藏