数据结构无向图简单路径

数据结构无向图简单路径

一.课程设计目的和要求
目的:锻炼学生对软件界面设计并进行实现的实践能力。
要求:(1)完成课程设计所给的所有功能。
(2)根据课程设计的特点设计出相应的画面。
二.课程设计环境
windows, DEVC++,Qt5.5
三.课程设计内容
(1)求出无向图中从起点到终点的所有简单路径。其中起点和终点可以由用户自行设定。
(2)求出无向图中从起点到终点的指定长度(如K)的所有简单路径。
四.课程设计过程
4.1任务定义和问题分析
(1)这是一道简单的DFS题目,内在的逻辑很简单,关键在于利用Qt设计相应界面。
4.2数据结构的选择和概要设计
数据结构无向图简单路径_第1张图片

4.3详细设计
数据结构无向图简单路径_第2张图片
4.3详细设计

(1)图的实现:

  1. 图的建立:
    建立了acr_node(边结点)、vex_node(顶点)和graph(无向图)三个结构体。利用邻接表的方式建立并初始化了无向图(题目要求)。其中Acr_node中存储了边的权值,用以计算路径的长度;vex_node加入了bool变量visited,作为该节点是否被访问的标志。
    2.起点到终点所有路径求解
    利用递归的方法,对于每一个结点执行以下操作。当该节点没有被标记时,访问该结点,将该结点标记,同时在路径中记录下该结点。然后如果该结点的存在邻接点,则对比该邻接点与终点,如果相同,记录下终点,输出路径;否则对其邻接点进行相同操作(递归)。然后访问该结点的下一个邻接点,并将该结点置为未标记。

  2. 起点到终点所有指定长度路径求解
    在2的基础上,加入一个记录路径上长度的变量length,当访问到终点且length与指定长度相等时,才输出路径。不过需要注意的,当起点与终点不同时,输出路径的判定条件需要再加上该邻接点未被访问过,否则就造成路径中存在两个相同的节点(非起点和终点),即路径不是简单路径,不符合条件。
    (2)ui界面外观设计:
    标签背景本身就是透明的,与界面整体的设计相符合,故不做更改;标签的字体颜色设计理念是与整体的界面相符合,大小为24号(不统一),字体为新宋体。
    效果图:
    在这里插入图片描述

  3. 输入框(LineEdit)
    输入框的背景设置为透明,并设为无边框;输入的字体颜色根据界面的整体设计采用不同的颜色,大小为20号,字体为新宋体。
    效果图:在这里插入图片描述

  4. 输出框(textBrowser)
    输出框的背景设置为透明,并设为无边框;输出的字体颜色根据界面的整体设计采用不同的颜色,大小为18号,字体为新宋体。
    效果图:

数据结构无向图简单路径_第3张图片
5. 无向图
(1)结点:多彩小圆圈,均匀的排布在界面的合适的部分。
(2)直线:从图的结点的圆心到另一个结点的圆心,不过考虑到整体效果,结点内的线段部分被覆盖掉;线段颜色根据整体设计采用不同的颜色,粗度为4,抗锯齿。
(3)整体效果:
数据结构无向图简单路径_第4张图片
6. 背景图
背景图不再是固定的图,加入了换肤功能,用户可以根据自己的喜好选择自己喜欢的背景。
7. 背景音乐
用户可以根据自己的喜好选择播放或者不播放歌曲,遇到不喜欢的歌曲可以选择切换。
(2)ui组件功能介绍及实现:

  1. start按钮
    调用了内部的求路径函数,用来求解路径。
  2. clear按钮
    用来清空输出路径的textBrowser,用于下一次路径的输出。
  3. skin按钮
    用来切换背景图。
  4. music按钮
    用来停止音乐的播放或者切换歌曲。

五.测试结果
测试数据:
起点: 1 终点: 1 长度: 2
预期结果:121, 131, 141
起点: 1 终点: 1
预期结果:1257641, 1257631,1253641, 12531, 121,1357641,13521, 1367521, 13641, 131,1467531, 1467521, 1463521, 14631, 141
数据结构无向图简单路径_第5张图片

六.课程设计收获
这次课程设计让我学会了使用Qt制造简单的界面,打破了以往exe文件编译出来后界面十分单调的尴尬场面。另外我往实现的界面中加入了更多的个性化的元素,比如切换背景图,播放不同的音乐,按钮、标签、输入框、输出框风格的设置等。
另外进一步了解了Qt各初始文件的作用,掌握了更多的函数和类,可以更熟练的去使用Qt开发自己满意的界面且可以更熟练的将功能函数接入到Qt文件中,将ui界面和功能函数更好的结合。
另外在求解简单路径的过程中,我对递归回溯的认知更加深刻,对DFS的掌握更加熟练,对图的认知更加清晰,对知识的运用能力显著提升。
我感觉最大的收获就是对于自学能力的锻炼。因为我之前并未接触过Qt,甚至不知道怎么去下载和安装Qt,怎么去创建第一个Qt项目。从一开始到现在一切都是靠百度。但是,我并没有在百度上找到对Qt的详细介绍,一步一步靠的都是不断的摸索。经常在我需要实现一些功能的时候,我百度到的往往是一行行代码,我很多时候根本都看不懂,甚至不知道出现的函数的作用和函数参数的意义是什么。对于这种情况,大多数时候我都会一遍遍的进行测试来确定每个参数的意义,有时候不想去测试八成是心态崩了。不仅如此,很多时候网上根本就查询不到我需要的功能怎么去实现,这时候我只有利用已有的知识取想尽办法去组合从而实现我需求的功能。
不仅如此,课程设计对于抗压能力的锻炼也是一级棒。每一次,当我信誓旦旦的说出我终于写完了之后,总会有bug跳出来向我示威,然后我又不得不去一遍遍的寻找错误原因,然后将其改正。一次次的大起大落让我有种看破红尘的感觉:代码固然好,不如出家去。不做红尘客,不生烦恼丝。很多的编程人员都会不经意的染上了“完美主义”思想,所以,即使Bug让我一遍遍地举起手中的键盘,我还是选择原谅它,这样生活才能过得去吧。我发现经过这几次课设,我自娱自乐的能力得到了长足的进步。
另外还有对函数的封装。函数的封装是编程中极其重要的一环,它不仅大大的提高了代码的可移植性,还可以帮助我们极快的锁定bug出现的位置,从而把它消灭。如果函数不封装,光是检查错误出现在哪里就能让我们头昏脑胀,更不用提去修正bug了。
细心也很重要,由于两个求解路径的函数实现有很多相同的地方。我便直接复制了过去,然后在复制的基础上进行修改。但是由于递归时的函数名没有修正过来,导致输出的结果并未达到预期结果。我本来以为是逻辑上的错误,便一次次的充当人性CPU去推导,结果花了很多时间还是没有找出来错误。最后逐行查代码才发现第二个函数实现中的递归的函数是第一个函数。当时心情很复杂。这也是我自己函数命名习惯不太好的原因,两个函数的名字只差了一个1。
总而言之,收获很大。虽然期间的经历不是那么愉快,但,不经历风雨,怎么见彩虹呢?人生总会遇到很多扎心的事情,无视即可,要在心中给快乐的事情留下足够的空间。

你可能感兴趣的:(数据结构课设)