本科课程【数据结构与算法】实验8 - 拓扑排序

x33g5p2x  于2022-04-10 转载在 其他  
字(2.3k)|赞(0)|评价(0)|浏览(567)

大家好,我是【1+1=王】, 热爱java的计算机(人工智能)渣硕研究生在读。
如果你也对java、人工智能等技术感兴趣,欢迎关注,抱团交流进大厂!!!
Good better best, never let it rest, until good is better, and better best.

近期会把自己本科阶段的一些课程设计、实验报告等分享出来,供大家参考,希望对大家有帮助。

博客更新至专栏【课程设计实验报告】:https://blog.csdn.net/weixin_43598687/category_11640051.html

一、 实验目的

  1. 掌握图的邻接矩阵存储结构
  2. 实现图的拓扑排序操作

二、 实验内容

1. 实验任务

输入图的节点信息,构造邻接表并输出邻接表和排序

2. 程序设计

1) 数据输入(输入哪些数据、个数、类型、来源、输入方式)
图的顶点数据(data)char字符型;
图的边关系(v1,v2)int 整型;
各边的权值(w)int 整型

2) 数据存储(输入数据在内存中的存储)
邻接表旳形式存储数据

3) 数据处理(说明处理步骤。若不是非常简单,需要绘制流程图)
①在有向图中选一个没有前驱的顶点且把它输出
②从图中删除该顶点和所有以它为尾的弧
③重复上述两步,直至全部顶点都输出,或者当图中不存在无前驱的顶点为止

4) 数据输出

三、 实验环境

  1. 操作系统:WINDOWS 10
  2. 开发工具:VC++ 2013
  3. 实验设备:PC

源代码(C++实现)

  1. #include<iostream>
  2. using namespace std;
  3. #define m 100
  4. #define n 6
  5. #define e 8
  6. struct {
  7. int s[n];
  8. int top;
  9. } stack;
  10. typedef struct node1
  11. {
  12. int info; //这个域就是本节点在数组中的位置
  13. int adjvertex;
  14. char data;
  15. struct node1 *nextarc;
  16. } glinklistnode; //这个是在后面邻接的节点
  17. typedef struct node2 {
  18. int vertexinfo;
  19. glinklistnode *firstarc;
  20. } glinkheadnode; //邻接表的数组,vertexinfo存的是每个点的入度
  21. //创建邻接链表
  22. void createAdjlist(glinkheadnode g[])
  23. {
  24. int i, j, k;
  25. glinklistnode *p;
  26. for (i = 0; i<n; i++)
  27. {
  28. g[i].vertexinfo = i;
  29. g[i].firstarc = 0;
  30. }//初始化每个节点在数组中的位置
  31. cout << "输入边节点关系:" << endl;
  32. for (k = 0; k<e; k++)
  33. {
  34. cin >> i >> j;
  35. p = (glinklistnode *)malloc(sizeof(glinklistnode));
  36. p->adjvertex = j;
  37. p->nextarc = g[i].firstarc;//使用的插入方式建立,后来的更接近根节点
  38. g[i].firstarc = p;//第一个邻接点是p
  39. }
  40. }
  41. //拓扑排序函数
  42. void toposort(glinkheadnode g[]) {
  43. int i, v, w, sum = 0, indegree[n];
  44. glinklistnode *p;
  45. for (i = 0; i < n; i++)
  46. {
  47. indegree[i] = 0;//初始化indegree数组,完全可以使用memset
  48. }
  49. for (i = 0; i < n; i++)
  50. {
  51. for (p = g[i].firstarc; p != 0; p = p->nextarc) //这一层for循环用来统计
  52. indegree[p->adjvertex]++;//经过两个for循环,即可把所有节点的入度算统计出来
  53. }
  54. for (i = 0, stack.top = -1; i < n; i++)
  55. {
  56. if (indegree[i] == 0)
  57. {
  58. stack.top++;
  59. stack.s[stack.top] = i;
  60. }//这个for循环用来入栈入度为0的节点
  61. }
  62. while (stack.top != -1)
  63. {
  64. cout << stack.s[stack.top]+1 << " ";
  65. sum = sum + 1;
  66. v = stack.s[stack.top];
  67. stack.top = stack.top - 1;//出栈top
  68. p = g[v].firstarc;//读取该节点的第一个邻接点
  69. while (p != 0) //遍历p的所有邻接点
  70. {
  71. w = p->adjvertex;
  72. indegree[w] = indegree[w] - 1;//因为前导节点会被删掉,因此它的入度值需要-1
  73. if (indegree[w] == 0) //如果它的入度等于0,就将这个节点也入栈
  74. {
  75. stack.top = stack.top + 1;
  76. stack.s[stack.top] = w;
  77. }
  78. p = p->nextarc;//往下走
  79. }
  80. }
  81. cout << endl;
  82. if (sum < n)
  83. {
  84. cout << "存在回路" << endl;
  85. }
  86. }
  87. int main() {
  88. glinkheadnode g[m];
  89. createAdjlist(g);
  90. toposort(g);
  91. system("pause");
  92. return 0;
  93. }

博客更新至专栏【课程设计实验报告】:https://blog.csdn.net/weixin_43598687/category_11640051.html

相关文章